GoogleMock: как ожидать точно один звонок с определенным аргументом и увидеть диагностику при сбое?

Может быть, хитрый вопрос, моя проблема в том, что если я напишу:

EXPECT_CALL(mock, handleMessage(_)).Times(0);                           // expectation #1
EXPECT_CALL(mock, handleMessage(Pointee(IsLike(aSpecificMessage))));    // expectation #2

… и метод handleMessage вызывается один раз, но с другим аргументом (не aSpecificMessage), то сбой выглядит так:

Mock function called more times than expected - returning default value.
Function call: handleMessage(0x8b5378)
Returns: false
Expected: to be never called
Actual: called once - over-saturated and active

Google Mock не печатает диагностику того, почему аргумент не соответствует предикату в ожидании №2.
Это предположительно потому, что ожидание № 1 потерпело неудачу первым (?).

Если я опускаю ожидание # 1, то ошибка является многословной, по типу:

Google Mock tried the following 1 expectation, but it didn't match:

../../test/Test.cpp:143: EXPECT_CALL(mock, handleMessage(Pointee(IsLike(aSpecificMessage))))...
Expected arg #0: points to a value that <....>
Actual: 0xfeaf18, which points to <.....>

Я использую пользовательский Matcher IsLike и я столкнулся с проблемой генерации очень явных причин несоответствия, я хотел бы, чтобы они были напечатаны. Я также не хотел бы отказываться от ожидания # 1, потому что это идет в разделе «по умолчанию», и по умолчанию я не хочу никаких вызовов на этот макет в оставшейся части тестов.

1

Решение

Похоже, вы должны использовать StrictMock модификатор шаблона. Давайте использовать этот простой класс и макет:

struct Foo
{
virtual void function(int) {
}
};

struct MockFoo: public Foo
{
MOCK_METHOD1(function, void(int x));
};

Давайте начнем с базового теста, который использует этот метод:

TEST(MockTest, basic_one_expectation)
{
MockFoo foo;
EXPECT_CALL(foo, function(4));
Foo& foo1(foo);
foo1.function(3);
}

Выход:

[RUN] MockTest.basic_one_expectation
неизвестный файл: ошибка

Неожиданный вызов фиктивной функции - возврат напрямую.
Вызов функции: функция (3)
Google Mock попробовал следующее 1 ожидание, но оно не совпало:

mock-test.cpp: 298: EXPECT_CALL (foo, function (4)) ...
Ожидаемый аргумент № 0: равен 4
Актуально: 3
Ожидаемый: будет вызван один раз
Актуально: никогда не звонил - неудовлетворен и активен
mock-test.cpp: 298: ошибка
Фактический счетчик вызовов функций не соответствует EXPECT_CALL (foo, function (4)) ...
Ожидаемый: будет вызван один раз
Актуально: никогда не звонил - неудовлетворен и активен
[FAILED] MockTest.basic_one_expectation (1 мс)

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

TEST(MockTest, basic_no_expectation)
{
MockFoo foo;
Foo& foo1(foo);
foo1.function(3);
}

Выход:

[RUN] MockTest.basic_no_expectation

GMOCK ПРЕДУПРЕЖДЕНИЕ:
Неинтересный вызов фиктивной функции - возврат напрямую.
Вызов функции: функция (3)
Трассировки стека:
[OK] MockTest.basic_no_expectation (1 мс)

Мы получаем предупреждение, но тест все равно проходит. Это не хорошо для вас. Посмотрим какой эффект StrictMock имеет:

TEST(MockTest, strict_no_expectation)
{
::testing::StrictMock<MockFoo> foo;
Foo& foo1(foo);
foo1.function(3);
}

Выход:

[RUN] MockTest.strict_no_expectation
неизвестный файл: ошибка
Неинтересный вызов фиктивной функции - возврат напрямую.
Вызов функции: функция (3)
[FAILED] MockTest.strict_no_expectation (0 мс)

Нам не нужно было явно говорить, что мы не хотим, чтобы функция вызывалась, но когда функция вызывается в любом случае, тест корректно завершается неудачей. Именно то, что вы хотели.

Наконец, давайте посмотрим, что происходит с StrictMock в случае, когда там являются явные ожидания для аргумента функции:

TEST(MockTest, strict_one_expectation)
{
::testing::StrictMock<MockFoo> foo;
EXPECT_CALL(foo, function(4));
Foo& foo1(foo);
foo1.function(3);
}

Выход:

[RUN] MockTest.strict_one_expectation
неизвестный файл: ошибка

Неожиданный вызов фиктивной функции - возврат напрямую.
Вызов функции: функция (3)
Google Mock попробовал следующее 1 ожидание, но оно не совпало:

mock-test.cpp: 307: EXPECT_CALL (foo, function (4)) ...
Ожидаемый аргумент № 0: равен 4
Актуально: 3
Ожидаемый: будет вызван один раз
Актуально: никогда не звонил - неудовлетворен и активен
mock-test.cpp: 307: сбой
Фактический счетчик вызовов функций не соответствует EXPECT_CALL (foo, function (4)) ...
Ожидаемый: будет вызван один раз
Актуально: никогда не звонил - неудовлетворен и активен
[FAILED] MockTest.strict_one_expectation (0 мс)

Диагностика показывает причину, по которой аргумент не совпадает, как и оригинал basic_one_expectation тест, показанный выше.

3

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector