2014-10-02 69 views
4

我主要使用GoogleMock的有序期望,因此所有EXPECT_CALL都写在testing::InSequence对象的范围内。Google Mock:为什么部分排序的期望难以满足总排序?

现在我想放松顺序,所以我分两个序列的期望。你会说测试应该通过,但没有 - 它失败了,抱怨未满足的先决条件。我应该如何推理?

编辑:我的代码的简化版本:

//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 
+0

你能写一些示例代码吗? – 2014-10-02 12:36:48

+0

只是添加了代码。 – haelix 2014-10-02 16:54:52

+1

补充说明:在第三期望附加'.RetiresOnSaturation()'可以修复部分订单情况。但不是我现实生活中的情况,这更复杂。 – haelix 2014-10-02 16:56:20

回答

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记录的这个现象还不够好。我仍在寻找更好的形式化。我怀疑这里使用的“偏序”概念有问题。

+0

你找到了解决这个问题的办法吗? – idij 2015-02-03 16:00:30

+0

没有。不是通用的。我相信一个通用的解决方案需要某种形式的回溯,但我没有更多的思考。 – haelix 2015-02-04 16:29:37

+0

谢谢。我能够解决这个问题的变种,因为我可以在任何一个块中区分方法A的参数值。然后让第一个模块中的methodA与之匹配,然后在第二个模块中匹配除该值以外的所有内容。显然,这不会适用于任何地方,它恰好适合我的问题。 – idij 2015-02-05 09:59:42