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, потому что оно находится в разделе «по умолчанию», и по умолчанию я не хочу, чтобы этот макет вызывался в остальных тестах.


person haelix    schedule 26.09.2014    source источник


Ответы (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
unknown file: Failure

Unexpected mock function call - returning directly.
    Function call: function(3)
Google Mock tried the following 1 expectation, but it didn't match:

mock-test.cpp:298: EXPECT_CALL(foo, function(4))...
  Expected arg #0: is equal to 4
           Actual: 3
         Expected: to be called once
           Actual: never called - unsatisfied and active
mock-test.cpp:298: Failure
Actual function call count doesn't match EXPECT_CALL(foo, function(4))...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] MockTest.basic_one_expectation (1 ms)

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

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

Выход:

[ RUN      ] MockTest.basic_no_expectation

GMOCK WARNING:
Uninteresting mock function call - returning directly.
    Function call: function(3)
Stack trace:
[       OK ] MockTest.basic_no_expectation (1 ms)

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

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

Выход:

[ RUN      ] MockTest.strict_no_expectation
unknown file: Failure
Uninteresting mock function call - returning directly.
    Function call: function(3)
[  FAILED  ] MockTest.strict_no_expectation (0 ms)

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

Наконец, давайте посмотрим, что происходит с 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
unknown file: Failure

Unexpected mock function call - returning directly.
    Function call: function(3)
Google Mock tried the following 1 expectation, but it didn't match:

mock-test.cpp:307: EXPECT_CALL(foo, function(4))...
  Expected arg #0: is equal to 4
           Actual: 3
         Expected: to be called once
           Actual: never called - unsatisfied and active
mock-test.cpp:307: Failure
Actual function call count doesn't match EXPECT_CALL(foo, function(4))...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] MockTest.strict_one_expectation (0 ms)

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

person Rob Kennedy    schedule 26.09.2014