Google Mock: почему частичный порядок ожиданий сложнее удовлетворить, чем полный порядок?

Я в основном использую упорядоченные ожидания с GoogleMock, поэтому все EXPECT_CALLс были написаны в рамках testing::InSequence объект.

Теперь я хочу ослабить порядок, поэтому я разделил ожидания на 2 последовательности. Вы бы сказали, что тест должен пройти, но нет — он проваливается, жалуясь на невыполненные предварительные условия. Как я должен рассуждать об этом?

Изменить: Сокращенная версия моего кода:

//InSequence s;                                     // uncomment this and it works
for (int i = 1; i <= 2; ++i)
{
{
//InSequence s;                             // uncomment this and it doesn't work

EXPECT_CALL(mock1, produceMessage(_))
.WillOnce(DoAll(SetArgReferee<0>(val1), Return(false)))
.WillOnce(DoAll(SetArgReferee<0>(val2), Return(false)))
.WillOnce(DoAll(SetArgReferee<0>(val2), Return(false)));

EXPECT_CALL(mock2, handleEvent(A<MyType>()));
EXPECT_CALL(mock2, handleMessage(NotNull()));
}
}

Так что, если InSequence вложен в for В цикле у меня должен быть частичный порядок, что является смягченным требованием по сравнению со случаем, когда InSequence находится снаружи.

Ошибка, которую я получаю:

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

И затем, в конце теста:

Actual function call count doesn't match EXPECT_CALL(mock2, handleMessage(NotNull()))...
Expected: to be called once
Actual: never called - unsatisfied and active

4

Решение

После некоторого прогресса в изучении кривой GoogleMock я попытаюсь ответить на свой собственный вопрос так, чтобы это было достаточно общим, чтобы быть полезным.

Давайте рассмотрим следующий пример полностью упорядоченных ожиданий:

{
InSequence s;

EXPECT_CALL(mock1, methodA(_));     // expectation #1
EXPECT_CALL(mock2, methodX(_));     // expectation #2

EXPECT_CALL(mock1, methodA(_));     // expectation #3
EXPECT_CALL(mock2, methodY(_));     // expectation #4
}

Теперь давайте разделим порядок на две части.

{
InSequence s;

EXPECT_CALL(mock1, methodA(_));     // expectation #1
EXPECT_CALL(mock2, methodX(_));     // expectation #2
}

{
InSequence s;

EXPECT_CALL(mock1, methodA(_));     // expectation #3
EXPECT_CALL(mock2, methodY(_));     // expectation #4
}

Намерение состоит в том, чтобы позволить ожиданиям от двух последовательностей «слиться», то есть иметь ожидание № 1 в качестве предварительного условия для № 2 и № 3 для № 4, но не более того.

Однако следующая последовательность вызовов будет соответствовать полностью упорядоченным ожиданиям, но не «частично упорядоченным»:

mock1.methodA();   // call #1
mock2.methodX();   // call #2
mock1.methodA();   // call #3
mock2.methodY();   // call #4

Причина: очевидно, почему полностью упорядоченные ожидания удовлетворяются: пример просто удовлетворяет их в том порядке, в котором они написаны. бытие InSequenceони уходят на пенсию, как только они удовлетворены.

Тем не менее, «частично упорядоченный» сценарий не работает, потому что вызов № 1 будет соответствовать ожиданию № 3, тогда вызов № 2 будет соответствовать ожиданию № 2, которое не может быть выполнено, потому что ожидание № 1 является предварительным условием. Хотя технически ожидания № 1 и № 3 идентичны, они выполняются в обратном порядке записи, так как они не принадлежат к одному и тому же порядку, следовательно, неудача.

У меня такое ощущение, что это явление недостаточно хорошо задокументировано в Google Mock. Я все еще ищу лучшую формализацию. Я подозреваю, что что-то не так с понятием «частичный порядок», которое используется здесь.

5

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


По вопросам рекламы [email protected]