2014-10-02 29 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