Я пытаюсь понять, как работают EXPECT_CALLs, и я застрял со странным поведением (на мой взгляд, странным). Допустим, мой код делает это (предположим, что есть макет, а f (int) - это его метод, также давайте предположим, что SomeNiceMock - это NiceMock):
void SomeMock::f(int) { ... }
NiceMock<SomeMock> someNiceMock;
void runCycle(int n) { someNiceMock.f(n); }
Теперь, если в тесте я сделаю следующее
EXPECT_CALL(someNiceMock, f(2)).Times(AtLeast(1));
runCycle(1);
runCycle(2);
::testing::Mock::VerifyAndClearExpectations(&mock);
Я получаю ошибку, что f (int), как предполагалось, было вызвано с 2, но было вызвано с 1.
Expected: to be called at least once
Actual: never called - unsatisfied and active
Если я сделаю это так:
runCycle(1);
EXPECT_CALL(someNiceMock, f(2)).Times(AtLeast(1));
runCycle(2);
::testing::Mock::VerifyAndClearExpectations(&mock);
Все работает.
Я могу жить с таким поведением, я просто не понимаю причину этого. someNiceMock - это NiceMock, поэтому он не должен жаловаться на то, что f (int) вызывается с каким-то другим аргументом, тогда ожидаемым, если на самом деле был вызов f (int) с ожидаемым аргументом. Второй вызов runCycle (2) вызвал f (2). Так почему же вызов f (1) не был просто проигнорирован и проверка не прошла? Это так, что если я укажу EXPECT_CALL даже для NiceMock, если этот вызов будет с другим аргументом (но позже будет другой вызов с правильным аргументом), тест провалится? Разве это не противоречит интуиции, учитывая, что это NiceMock, и вызов f (2) действительно произошел в обоих случаях?
РЕДАКТИРОВАТЬ : И как мне тогда проверить такое поведение? Допустим, у меня есть какой-то генератор чисел, и я хочу проверить, что при вызове 10 раз он возвращает 5, по крайней мере, 3 раза (и мне плевать на другие результаты. Я ожидал бы закодировать его так (извините, если я запутался синтаксис, я не так хорош в издевательстве над Google):
struct INumberGeneratorSink {
virtual void consumeNumber(int number) = 0;
};
struct NumberGeneratorSink : public INumberGeneratorSink {
void consumeNumber(int number) override { ... }
};
struct NumberGeneratorSinkMock : public INumberGeneratorSink {
MOCK_METHOD1(consumeNumber, void(int number));
};
void numberGeneratorFunction(INumberGeneratorSink &sink)
{
for (int i = 0; i < 10; i++)
{
sink.consumeNumber(getNumberFromSomewhere());
}
}
NumberGeneratorSinkMock sinkMock;
NiceMock<NumberGeneratorSinkMock> niceSinkMock;
EXPECT_CALL(niceSinkMock, consumeNumber(5)).Times(AtLeast(3));
numberGeneratorFunction(niceSinkMock);
Как я могу кодировать подобные вещи? Если есть какая-то синтаксическая ошибка, пожалуйста, исправьте меня, но мой вопрос больше напоминает - если я забочусь только о том, чтобы потребление, номер 3 вызывался со значением 5, а меня не заботило остальное, как я могу его кодировать? Должен ли я написать что-то вроде:
// not sure about syntax for Any(),
// maybe it doesn't exist and has to be AtLeast(1)
EXPECT_CALL(niceSinkMock, consumeNumber(_)).Times(Any());
EXPECT_CALL(niceSinkMock, consumeNumber(5)).Times(AtLeast(3));
Будет ли это работать? Не будет ли первый EXPECT_CALL просто соответствовать всему, и тест будет пройден, даже если в качестве аргумента никогда не будет вызван статистически значимый параметр «5»?