ON_CALL AND EXPECT_CALL для одного и того же метода с различными сопоставителями параметров генерирует насыщенную и активную ошибку - PullRequest
0 голосов
/ 08 октября 2019

В этом примере ниже я получу следующее поведение:

EXPECT_CALL (barMock, doBar (7)) ... Ожидаемый аргумент # 0: равен 7 Фактический: 5 Ожидаемый: кбыть вызванным один раз Факт: вызванным один раз - насыщенный и активный

#include <gmock/gmock.h>
#include <gtest/gtest.h>

class IBar
{
public:
    virtual bool doBar(int barParam) = 0;
};

class BarMock : public IBar
{
public:
    MOCK_METHOD1(doBar, bool(int));
};

class Foo
{
public:
    Foo(IBar& bar_)
        : bar{ &bar_ }
    {

    }
    void doFoo()
    {
        bar->doBar(7);
        bar->doBar(5);
    }
    IBar* bar;
};

class FooBarTest : public ::testing::Test
{
public:
    void SetUp() override
    {
        ON_CALL(barMock, doBar(testing::_)).WillByDefault(testing::Return(true));
    }

    testing::NiceMock<BarMock> barMock;
};

TEST_F(FooBarTest, OnCallExpectCallSameMethod)
{

    Foo               foo(barMock);

    ON_CALL(barMock, doBar(5)).WillByDefault(testing::Return(true));
    EXPECT_CALL(barMock, doBar(7)).WillOnce(testing::Return(true));

    foo.doFoo();

}

Тестовые версии Google, проверенные:

  • 1.8.0
  • 1.8.1

  1. Это должно вызвать ошибку?
  2. Как Google Test устанавливает порядок звонков? Имеет ли EXPECT_CALL более высокий приоритет только в этом сценарии?

1 Ответ

0 голосов
/ 10 октября 2019

Да, это должно быть ошибкой. Одна из политик GoogleMock заключается в том, что в случае возможной неоднозначности лучше выдать ошибку, чтобы заставить пользователя явно заявить о своем намерении.

Добавление макроса EXPECT_CALL эффективно говорит: «Я забочусь о вызовах этого метода». Всякий раз, когда установлен EXPECT_CALL, GoogleMock будет пытаться сопоставить все EXPECT_CALL, которые он видел, в обратном порядке объявления (поэтому самые последние определенные ожидания сопоставляются первыми).
Одна из причин такого дизайна - разрешить переопределение меньшеконкретные ожидания с более конкретными (например, в конструкторе тестового устройства вы устанавливаете менее ограничительные ожидания, но для определенных тестов вы хотите более точно соответствовать). Документация .

Однако есть способ "игнорировать" уже выполненные ожидания, добавив .RetiresOnSaturation()

TEST_F(FooBarTest, OnCallExpectCallSameMethod)
{
    Foo foo(barMock);
    ON_CALL(barMock, doBar(5)).WillByDefault(testing::Return(true));
    EXPECT_CALL(barMock, doBar(7))
        .WillOnce(testing::Return(true))
        .RetiresOnSaturation();

    foo.doFoo();
}

RetiresOnSaturation()ожидания будут удалены после того, как он будет насыщен (то есть будет вызван столько раз, сколько ожидалось). GoogleMock будет пропускать ожидания, оставшиеся без ответа, до тех пор, пока все еще не будут выбраны ожидания (если все они ушли в отставку, то все равно выдает ошибку).


Если вам, однако, необходимо принимать вызовы doBar(5) до doBar(7), тогда единственный способ сделать это - определить его как ожидание:

TEST_F(FooBarTest, OnCallExpectCallSameMethod)
{
    Foo foo(barMock);
    EXPECT_CALL(barMock, doBar(5)).WillRepeatedly(testing::Return(true));
    EXPECT_CALL(barMock, doBar(7))
        .WillOnce(testing::Return(true))
        .RetiresOnSaturation();

    foo.doFoo();
}

RetiresOnSaturation() все еще требуется из-за LIFO (последний вв первую очередь) обработка ожиданий.

...