2017-10-19 2 views
2

저는 GoogleTest와 GoogleMock을 시작했습니다. "for dummies" documentation 읽기의 예는 Turtle에 의존하는 Painter 클래스 테스트 :역 참조 포인터를 사용할 때 EXPECT_CALL 테스트가 갑자기 실패하는 이유는 무엇입니까?

실제 개체를 - Turtle.h

class Turtle { 
public: 
    virtual ~Turtle() {} 
    virtual void PenDown() = 0; 
}; 

모의 객체 - 모의 - turtle.h

class MockTurtle : public Turtle { 
public: 
    MOCK_METHOD0(PenDown, void()); 
}; 

테스트중인 코드 - Painter.h

class Painter { 
public: 
    Painter(Turtle *turtle){}; 
}; 

단위 테스트 -이 작업은 turtle.PenDown() 방법은 Painter 생성자에서 호출 여부를 테스트하기위한 것입니다

test_painter.cpp.

TEST(PainterTest, CanDrawSomething) { 
    MockTurtle turtle; 
    EXPECT_CALL(turtle, PenDown()) 
      .Times(AtLeast(1)); 
    Painter painter(&turtle); 
} 

이 테스트는 PenDown()이 호출되지 않기 때문에 올바르게 실패합니다.

그러나 역 참조 포인터를 사용하여 MockTurtle으로 변경하면 이 잘못 입력됩니다.이 전달됩니다.

왜 역 참조 된 포인터를 사용할 때이 테스트가 통과합니까? 내 코드에 아무데도 PenDown()이 호출됩니다.

자세한 내용은 MockTurtle에 대한 포인터를 사용하여 다른 테스트에서 사용할 수 있도록 테스트 픽스처에서 초기화 할 수 있습니다.

+0

최신 버전의 Google Test를 사용하고 있으며 예상대로 작동합니다. 최신 버전의 Google Test를 사용해보십시오 – Asesh

+0

Google 테스트 (github에서 가져온 것)의 최신 버전을 사용하고 있습니다. 테스트 실행 파일을 만들기 위해 특별한 작업을하고 있습니까? 내 빌드 명령 :'g ++ -I googlemock/include -I googletest/include -I ../source -L googlemock -lgmock_main test_painter.cpp -o test_painter' – donturner

+0

특별한 것은 없지만 Visual C++를 사용하며 두 테스트 모두 실패합니다. – Asesh

답변

4

포인터를 삭제하지 마십시오.

그리고 삭제하는 것을 잊지 않고 PenDown()이 푸시됩니다. 멤버는 호출되지 않습니다.그러나 결과를 프레임 워크에보고하는 것은 소멸자MockTurtle입니다.

누출되면 아무 것도보고되지 않습니다. 프레임 워크는 피드백을받지 않기 때문에 빈 테스트 (공백으로 통과 함)를 실행했다고 생각합니다.

turtle이 자동 저장 기간을 갖는 객체 (포인터가 아님) 인 경우 소멸자는 범위 종료시 자동으로 호출됩니다. 그것이 오류가보고 된 이유입니다.

이것은 상용구 용으로 RAII을 사용하는 GoogleMock입니다.

2

@ StoryTeller의 탁월한 대답 외에도 추가 배경을 추가하는 것이 유용 할 것이므로이 문제로 아무도 알아 내지 못한다고 생각했습니다.

테스트 주자로 CLion을 사용하고 있으며 this bug이 발생 했으므로 이후에 발생한 오류는 이고 테스트가 실행되지 않았습니다. 터미널에서 테스트 바이너리를 실행하면 다음과 같이 나타납니다.

./test_painter --gtest_filter=* --gtest_color=no 
Running main() from gmock_main.cc 
[==========] Running 1 test from 1 test case. 
[----------] Global test environment set-up. 
[----------] 1 test from PainterTest 
[ RUN  ] PainterTest.CanDrawSomething 
[  OK ] PainterTest.CanDrawSomething (0 ms) 
[----------] 1 test from PainterTest (0 ms total) 

[----------] Global test environment tear-down 
[==========] 1 test from 1 test case ran. (0 ms total) 
[ PASSED ] 1 test. 

/Users/donturner/PCode/workspace-kinetis/blinky/tests/test_painter.cpp:13: ERROR: this mock object (used in test PainterTest.CanDrawSomething) should be deleted but never is. Its address is @0x7fc06f402720. 
ERROR: 1 leaked mock object found at program exit. 

그래서 포인터를 삭제하는 것을 잊어 버리고있었습니다. 나는 내 테스트의 끝에 다음 줄을 추가 :

delete turtle; 

그리고 헤이 프레스토 테스트가 제대로 실패 포인터 결과를 삭제 잊는 사람이 왜 PenDown()에 말해 줄 수 있다면

$ ./test_painter --gtest_filter=* --gtest_color=no 
Running main() from gmock_main.cc 
[==========] Running 1 test from 1 test case. 
[----------] Global test environment set-up. 
[----------] 1 test from PainterTest 
[ RUN  ] PainterTest.CanDrawSomething 
/Users/donturner/PCode/workspace-kinetis/blinky/tests/test_painter.cpp:13: Failure 
Actual function call count doesn't match EXPECT_CALL(*turtle, PenDown())... 
     Expected: to be called at least once 
      Actual: never called - unsatisfied and active 
[ FAILED ] PainterTest.CanDrawSomething (0 ms) 
[----------] 1 test from PainterTest (0 ms total) 

[----------] Global test environment tear-down 
[==========] 1 test from 1 test case ran. (0 ms total) 
[ PASSED ] 0 tests. 
[ FAILED ] 1 test, listed below: 
[ FAILED ] PainterTest.CanDrawSomething 

1 FAILED TEST 

라고중인 나는 가장 관심을 가질 것이다!

+0

예, 이제이 문제를 재현 할 수 있습니다. 재미있는 사운드 – Asesh

관련 문제