我主要在GoogleMock中使用有序期望,因此所有EXPECT_CALL
都写在testing::InSequence
对象的范围内。
现在,我想放宽顺序,因此我将期望分为两个序列。您会说测试应该通过,但不能-它失败,提示未满足的先决条件。我应该怎么做呢?
编辑:我的代码的简化的版本:
//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
最佳答案
在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记录的现象还不够。我仍在寻找更好的形式化。我怀疑这里使用的“部分订单”概念有问题。