Кто-нибудь когда-нибудь видел странное поведение в gmock при выполнении оператора ON_CALL с оператором EXPECT_CALL? Для меня оператор EXPECT_CALL в следующем коде не работает (на самом деле он не применяет часть Times):
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).
У вас есть другая ошибка в вашем исходном коде, которая не упоминается в вашем вопросе. Код, приведенный в вопросе, ведет себя так, как вы ожидаете, если вы создаете минимальный автономный пример.
Например, следующий код:
#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();
}
Mock::VerifyAndClearExpectations(&myMockObject);
Это добилось цели. Я все еще не уверен, как ожидания управляются за кулисами, но это заставило меня работать.
Любое дальнейшее объяснение этого будет с благодарностью.