2017-05-23 2 views
0

한다고 가정 연결 교환 수 :은 내가 클래스가 QObject를 아이 유지 신호와 슬롯

class Foo : public QObject{ 
Q_OBJECT 
public: 
    ... 
private: 
    Bar* m_bar; 
} 

그리고 어떤 이유를, 나는 DerivedBar의 개체에 대한 포인터로 m_bar를 교체하고 싶습니다. 가장 자주 사용되는 사례는 단위 테스트를 위해 MockBar 객체 (google mock 프레임 워크 사용)로 대체하려는 경우입니다.

Foo(Bar* bar, QObject* parent) 

그냥 m_bar 따라 설정 :

은 지금은 대부분의 경우에, 난 그냥 같은 것을 할 생성자를 확장 할 수 알고있다.

하지만 문제는 클래스가 QWidgets이고 Qt 디자이너를 통해 어셈블 할 때입니다. Foo와 Bar는 위젯이고, Bar는 디자이너의 Foo 내부에 위치한다고 상상해보십시오. 그들의 연결은 디자이너를 통해 (즉, qml 파일에 저장되어) 설정됩니다. (단지 기능려고, 여기에 어떤 메모리 누수를 무시)를

Bar* bar = foo.findChild<Bar*>(); 
bar = new MockBar(&foo); 

하지만 기대치를 설정하기 위해 갈 때, 기존의 하나처럼 연결하지 않는 것 : 내가 좋아하는 뭔가를 시도했습니다. 신호에 대한 응답으로 슬롯이 호출되지 않습니다. 나는 이것이 연결이 이루어지는 방식 때문에 전적으로 의외 였다고 생각하지 않지만, 내가 찾고있는 효과를 얻을 수있는 방법이 있는지 궁금합니다.


(NB : 나를 위해 문제는 궁극적으로 할 수 있습니다 : 여기 내가 찾은 좋은 대답이야 ++

답변

0

을 다하기위한 몇 가지 옵션을 제한 않습니다 QT 4.8 및 GCC 4.6을 사용하여, 지금은 ui 파일에서 생성 된 QWidgets.하지만 Ui :: FooWidget 클래스는 기능상 그냥 pimpl 패턴이므로 하나의 로컬 복사본에 대한 포인터를 만들고 Foo의 생성자를 수정하여 UI 구현을 선택적으로 삽입 할 수있게합니다. BarWidget에 대한 직접 함수 호출을 만들 때, 그 ui의 'barWidget'객체를 MockBarWidget으로 대체하고 기대치를 설정하고 테스트를 수행 할 수 있습니다. 이전의 대답은 두 위젯 간의 상호 작용 s는 신호/슬롯 연결 중 하나입니다.


이전 답변 :

는 여기에 지금까지 발견 한 하나의 대답,하지만 난 그것을처럼 많이하지 않습니다 :

Bar* bar = foo.findChild<Bar*>(); 
bool connectTest = QObject::connect(&foo, SIGNAL(setValue(int)), bar, SLOT(setValue(int)), Qt::UniqueConnection); 
ASSERT_FALSE(connectTest); 
bar = new MockBar(&foo); 
connectTest = QObject::connect(&foo, SIGNAL(setValue(int)), bar, SLOT(setValue(int)), Qt::UniqueConnection); 
ASSERT_TRUE(connectTest); 
//... rest of test 

아마 일부에서 전체를 포장 할 수 일종의 도우미 함수이며 그 함수는 신호와 슬롯이 메소드 포인터가 될 수있는 C++ 11/Qt5에서 더 좋을 수 있습니다. 그러나 나는 그것을 할 수있는 더 쉬운 방법을 놓치고 있는지 궁금해.


편집 :이 패턴은 나에게 시험 행동의 유효한 테스트를주고 있었다의 가양, 첫 번째 'connectTest'부분을주고 있었다 밝혀졌습니다. 이 결함은 Foo가 bar에 신호를 보내지 않고 bar의 메서드를 호출 할 때 더 분명합니다. 모의은이 패턴을 통해 주입되지 않습니다.

+0

다음 질문 : 연결 목록을 열거 할 수있는 방법이 있습니까? 공식적으로는 아니지만 비공개 API를 사용하는 것은 쉬운 일이며, 테스트에만 사용되므로 큰 도움이되지 않습니다. 호환 가능한 슬롯이있는 다른 객체에 연결의 슬롯 끝점을 전송할 수도 있으므로 연결을 복제 할 필요가 없습니다. 일부 연결을 복제하는 것은 힘들거나 불가능합니다. 펑터 (functor)와의 연결. –

+0

고마워, 나는 내 문제의 일부를 해결할 수있는 방법으로 그 접근법을 조사 할 것이다. 하지만 신호/슬롯 동작을 검사하는 대신 바에서 직접 함수 호출을 시도하는 경우 여전히 문제가 될 수 있습니다. – shavera