2013-05-22 5 views
1

Кто-нибудь видел замеченное нечетное поведение в gmock при выполнении инструкции ON_CALL с помощью оператора EXPECT_CALL? Для меня заявление EXPECT_CALL в следующем коде не работает (он фактически не применять часть Times):Нечетное поведение при использовании ON_CALL перед EXPECT_CALL с помощью Gmock

ON_CALL(myMockObject, myMockMethod()).WillByDefault(Return("hello mock"))); 
EXPECT_CALL(myMockObject, myMockMethod()).Times(99999); 
myMockObject.myMockMethod(); 

Другие решения, которые я пробовал:

Переопределение myMockMethod из суперкласса и попросите его просто написать строковый литерал. Проблема в том, что я не могу определить, сколько раз он был вызван позже.

Пропустив ON_CALL часть в пользу чего-то вроде этого:

EXPECT_CALL(myMockObject, myMockMethod()) 
    .Times(1) 
    .WillRepeatedly(Return("hello mock")); 

Это приводит к ошибке компиляции.

Также обратите внимание, что строковый литерал, который я использую в этом примере, является обычным в реальности, и то, что gmock не сможет найти значение по умолчанию (например, bool).

+1

С '.Times (1)' вы пробовали 'WillOnce (Return (" hello mock "))'? – Steve

ответ

0
Mock::VerifyAndClearExpectations(&myMockObject); 

Это сделало трюк. Я все еще не уверен, как ожидания управляются за кулисами, но это заставило меня работать.

Любое дальнейшее объяснение этого было бы весьма признательно.

2

У вас есть другая ошибка в исходном коде, который не упоминается в вашем вопросе. Код, указанный в вопросе, ведет себя так, как вы ожидали, если вы построите минимальный автономный пример.

Например, следующий код:

#include <string> 
#include "gmock/gmock.h" 

using ::testing::Return; 

struct MyClass { 
    virtual ~MyClass() {} 
    virtual std::string myMockMethod() = 0; 
}; 

struct MyMockClass : MyClass { 
    MOCK_METHOD0(myMockMethod, std::string()); 
}; 

TEST(MyClass, Fails) { 
    MyMockClass myMockObject; 
    ON_CALL(myMockObject, myMockMethod()).WillByDefault(Return("hello mock")); 
    EXPECT_CALL(myMockObject, myMockMethod()).Times(99999); 
    myMockObject.myMockMethod(); 
} 

TEST(MyClass, Passes) { 
    MyMockClass myMockObject; 
    EXPECT_CALL(myMockObject, myMockMethod()).Times(1).WillRepeatedly(Return("hello mock")); 
    myMockObject.myMockMethod(); 
} 

int main(int argc, char **argv) { 
    testing::InitGoogleTest(&argc, argv); 
    return RUN_ALL_TESTS(); 
} 

производит следующее (ожидаемый) результат:

[==========] Running 2 tests from 1 test case. 
[----------] Global test environment set-up. 
[==========] 2 tests from MyClass 
[ RUN  ] MyClass.Fails 
..\src\main.cc(18): error: Actual function call count doesn't match EXPECT_CALL(myMockObject, myMockMethod())... 
     Expected: to be called 99999 times 
      Actual: called once - unsatisfied and active 
[ FAILED ] MyClass.Fails (0 ms) 
[ RUN  ] MyClass.Passes 
[  OK ] MyClass.Passes (0 ms) 
[----------] 2 tests from MyClass (2 ms total) 

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

1 FAILED TEST 

Если вы хотите, чтобы ваш фиктивный объект, который пройдет в испытательном стенде , вы можете сделать:

class MyClassTest : public testing::Test { 
protected: 
    MyMockClass myMockObject_; 
}; 

TEST_F(MyClassTest, Fails) { 
    ON_CALL(myMockObject_, myMockMethod()).WillByDefault(Return("hello mock")); 
    EXPECT_CALL(myMockObject_, myMockMethod()).Times(99999); 
    myMockObject_.myMockMethod(); 
} 
+0

Должен ли быть реализован мой макет объекта внутри каждого метода тестирования? Я знаю, что это хорошая форма (и автономная), но я обычно пытаюсь создать общие объекты в каком-то приспособлении. – Stubbs

+1

Вы можете это сделать. Я обновил свой ответ. – Fraser