2011-04-14 28 views
6

我有一個奇怪的問題,與Easymock 3.0和JUnit 4.8.2。 僅當從Maven執行測試而不是從Eclipse執行測試時纔會出現此問題。更多的匹配器記錄比預期 - Easymock從Maven而不是從Eclipse中失敗

這是單元測試(很簡單):

... 
protected ValueExtractorRetriever mockedRetriever; 
... 

@Before 
public void before() { 
    mockedRetriever = createStrictMock(ValueExtractorRetriever.class); 
} 

@After 
public void after() { 
    reset(mockedRetriever); 
} 

@Test 
public void testNullValueExtractor() { 
    expect(mockedRetriever.retrieve("PROP")).andReturn(null).once(); 
    replay(mockedRetriever); 

    ValueExtractor retriever = mockedRetriever.retrieve("PROP"); 
    assertNull(retriever); 

    assertTrue(true); 
} 

我也得到:

java.lang.IllegalStateException:1點的匹配預期,2記錄。

奇怪的是我甚至沒有使用參數匹配器。這是測試的唯一方法!並使它更糟糕,它可以從Eclipse中運行,並從Maven中失敗!

我發現幾個環節,其並沒有提供給我一個答案:

如果我改變了單元測試,並添加一個方法(該方法不使用參數匹配器):

@Test 
public void testIsBeforeDateOk() { 
    expect(mockedRetriever.retrieve((String)anyObject())).andReturn(new PofExtractor()).anyTimes(); 
    replay(this.mockedRetriever); 

    FilterBuilder fb = new FilterBuilder(); 
    assertNotNull(fb); 

    CriteriaFilter cf = new CriteriaFilter(); 
    assertNotNull(cf); 
    cf.getValues().add("2010-12-29T14:45:23"); 
    cf.setType(CriteriaType.DATE); 
    cf.setClause(Clause.IS_BEFORE_THE_DATE); 

    CriteriaQueryClause clause = CriteriaQueryClause.fromValue(cf.getClause()); 
    assertNotNull(clause); 
    assertEquals(CriteriaQueryClause.IS_BEFORE_THE_DATE, clause); 

    clause.buildFilter(fb, cf, mockedRetriever); 
    assertNotNull(fb); 

    Filter[] filters = fb.getFilters(); 
    assertNotNull(filters); 
    assertEquals(filters.length, 1); 

    verify(mockedRetriever); 

    logger.info("OK"); 
} 

this las t方法通過測試,但不通過另一個測試。這怎麼可能!?!?!

問候, 尼科

更多鏈接:

「bartling.blogspot.com/2009/11/using-argument-matchers-in-easymock-and.html」

「WWW .springone2gx.com /博客/ scott_leberknight/2008/09/the_n_matchers_expected_m_recorded_problem_in_easymock」

「stackoverflow.com/questions/4605997/3-matchers-expected-4-recorded」

+0

你使用的是m2eclipse嗎?你的pom是怎樣的? – khmarbaise 2011-04-14 11:36:20

+0

我是。不幸的是,這是一個非常大的問題,因爲這是許多測試工作中的一個測試(這使得更奇怪的)來自許多maven模塊之一。最奇怪的是,如果我啓用maven-surefire-report並同時運行線程,它就可以工作!但它取決於環境(Hudson失敗,但它可以在我的開發框中工作) – Nico 2011-04-14 11:43:24

+0

您是否已經刪除了完整的本地Maven存儲庫並從開發人員的頭上對其進行了測試? – khmarbaise 2011-04-14 11:46:37

回答

5

我有一個非常類似的問題,並在下面的鏈接中寫下我的發現。 http://www.flyingtomoon.com/2011/04/unclosed-record-state-problem-in.html(剛剛更新)

我相信在另一個測試中的問題會影響您當前的測試。問題出在另一個測試課上,它會影響你的測試。爲了找到真正問題的地方,我建議逐個禁用有問題的測試,直到您通知失敗的測試。

其實這就是我所做的。我一個一個地禁用了失敗的測試,直到我發現有問題的測試。我發現了一個引發異常並通過「@extected」註釋捕獲而不停止錄製的測試。

+0

> Thx很多!我禁用了所有的測試,並通過所有的測試,直到我找到了這樣的一個,這也導致我另一個錯誤的測試課,我修好了,現在一切正常。 Thx爲更新後的文章:) – Nico 2011-04-18 09:22:13

0

相信第一錯誤消息

java.lang.IllegalStateException:1個 匹配器預期,2記錄下來。

表示您的mockedRetriever方法調用了兩次,但測試期望它被調用一次。所以你的Eclipse和Maven的配置不同。

我沒有理由在測試後重置模擬。請記住,JUnit會爲每個測試方法創建新的類實例。

編輯:

什麼,爲什麼最後的測試方法傳遞答案的原因是:

expect(mockedRetriever.retrieve((String)anyObject())).andReturn(new PofExtractor()).anyTimes(); 

但在你的第一個測試方法是:

expect(mockedRetriever.retrieve("PROP")).andReturn(null).once(); 

爲相當於:

expect(mockedRetriever.retrieve("PROP")).andReturn(null); 
+0

@Constantiner 1->'mockedRetriever'只能被調用一次,如您在方法中看到的:'testNullValueExtractor'。我看不到2個「行爲」在哪裏被記錄下來...... 2->重置在那裏,因爲最初我有多個測試,我重複使用了相同的模擬,說實話,我不知道有多個測試實例被實例化。很高興知道! 3->我不明白你說什麼。問題是,如果我只離開(並刪除另一個)方法:'testIsBeforeDateOk'它失敗!那就是問題所在!!!! 4->最後,Maven創建了我的eclipse項目,而不是我。 – Nico 2011-04-14 13:12:26

+0

對不起!我沒有看到你的第一個代碼中沒有被測試的類,並且你只是直接調用了mock對象。如果在第一個代碼示例中在'testNullValueExtractor()'方法的末尾添加'verify(mockedRetriever);'會怎麼樣? – Constantiner 2011-04-14 13:25:51

+0

@Constantiner我加了它,仍然在「記錄模式」下失敗。我很確定這不是測試本身的問題,而是其他問題。我會嘗試禁用其他測試,看看這是否有效,因爲這實際上沒有任何意義,是嗎? – Nico 2011-04-14 15:12:25

0

最近我們遇到了這個問題,當我們運行整個測試套件(1100多個測試用例)時,它只是開了個頭。最後,我發現我可以在正在爆炸的測試中放置一個斷點,然後退回到Eclipse已經執行的測試列表中,尋找之前已經錯誤地設置了模擬的測試用例。

我們的問題竟然是有人在EasyMock.expect(...)聲明之外使用EasyMock.anyString()。果然,它在失敗之前完成了兩次測試。

所以基本上,發生的情況是,在期望聲明之外濫用匹配器會中毒EasyMock的狀態,並且下一次我們嘗試創建模擬時,EasyMock會炸燬。

相關問題