Google Mock:为什么部分期望期望比总期望更难满足?

问题描述 投票:4回答:2

我主要在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
c++ googlemock expectations
2个回答
5
投票

在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记录的这种现象还不够好。我仍在寻找更好的形式化。我怀疑此处使用的“部分订单”概念有问题。


0
投票

[查看您的问题和答案,我认为您的案例是DAG(有向无环图)的典型示例,可以通过EXPS_CALL的InSequence子句解决(而不是:: testing ::名称空间的InSeqeunce类)。请参见gmock Cookbook的说明here。您的答案中提供的示例测试可以通过以下方式解决:

Sequence s1, s2;
EXPECT_CALL(mock1, methodA(_)).InSequence(s1, s2);
EXPECT_CALL(mock2, methodX(_)).InSequence(s1);
EXPECT_CALL(mock2, methodY(_)).InSequence(s2);

上面的测试代码将确保在methodX和methodY之前调用methodA。

© www.soinside.com 2019 - 2024. All rights reserved.