2009-09-30 25 views
1

以下是我使用自己的匹配器打開的一個測試。我知道在這種情況下,我可以使用標準匹配器,但在我的真實代碼中,我需要更復雜的代碼。easymock - 匹配器和多個呼叫

測試通過 - 打勾VG。 問題是,似乎有一個額外的電話IArgumentMatcher.matches()方法返回false,但測試通過。

我得到的輸出是:

30-09-2009 16:12:23 [main] ERROR - MATCH - expected[aa], actual[aa] 
30-09-2009 16:12:23 [main] ERROR - MISMATCH - expected[aa], actual[bb] 
30-09-2009 16:12:23 [main] ERROR - MATCH - expected[bb], actual[bb] 

所以,問題是爲什麼我收到的不匹配行, 和我做了一些錯誤的?

測試代碼是:

package uk.co.foo; 

import static org.easymock.EasyMock.createMock; 
import static org.easymock.EasyMock.expect; 
import static org.easymock.EasyMock.replay; 
import static org.easymock.EasyMock.reset; 
import static org.easymock.EasyMock.verify; 
import junit.framework.TestCase; 

import org.apache.log4j.Logger; 
import org.easymock.EasyMock; 
import org.easymock.IArgumentMatcher; 

/** 
* 
*/ 
public class BillTest extends TestCase { 

    private static Logger mLogger = Logger.getLogger(BillTest.class); 

    private BillInterface mMockBill; 

    public void testTwoCalls() throws Exception { 
    BillsTestClass sut = new BillsTestClass(); 
    sut.setDao(mMockBill); 

    expect(mMockBill.method1(eqBillMatcher("aa"))).andReturn(""); 
    expect(mMockBill.method1(eqBillMatcher("bb"))).andReturn(""); 
    replay(mMockBill); 

    //test method 
    sut.doSomething("aa"); 
    sut.doSomething("bb"); 

    verify(mMockBill); 
    } 

    public String eqBillMatcher(String aIn) { 
    EasyMock.reportMatcher(new BillMatcher(aIn)); 
    return null; 
    } 

    @Override 
    protected void setUp() throws Exception { 
    super.setUp(); 
    mMockBill = createMock(BillInterface.class); 
    } 


    @Override 
    protected void tearDown() throws Exception { 
    super.tearDown(); 
    reset(mMockBill); 
    } 

    public class BillsTestClass { 
    private BillInterface mDao; 
    public void setDao(BillInterface aDao) { 
     mDao = aDao; 
    } 

    public void doSomething(String aValue) { 
     mDao.method1(aValue); 
    } 
    } 

    public interface BillInterface { 
    String method1(String aValue); 
    } 

    public class BillMatcher implements IArgumentMatcher { 
    private String mExpected; 

    public BillMatcher(String aExpected) { 
     mExpected = aExpected; 
    } 

    /** 
    * @see org.easymock.IArgumentMatcher#matches(java.lang.Object) 
    * {@inheritDoc} 
    */ 
    public boolean matches(Object aActual) { 
    if (aActual.equals(mExpected)) { 
     mLogger.error("MATCH - expected[" + mExpected + "], actual[" + aActual + "]"); 
     return true; 
    } 
    mLogger.error("MISMATCH - expected[" + mExpected + "], actual[" + aActual + "]"); 
    return false; 
    } 

    /** 
    * @see org.easymock.IArgumentMatcher#appendTo(java.lang.StringBuffer) 
    * {@inheritDoc} 
    */ 
    public void appendTo(StringBuffer aBuffer) { 
    aBuffer.append("boo("); 
    } 
    } 
} 

回答

0

快速播放,它看起來像你沒有定義爲了這一點的東西應該可以預料的。每次您對模擬進行調用時,它都會按順序遍歷所有期望,直到找到匹配並且之前未被調用的模擬。

所以有:

expect(mMockBill.method1(eqBillMatcher("aa"))).andReturn(""); 
expect(mMockBill.method1(eqBillMatcher("aa"))).andReturn(""); 
expect(mMockBill.method1(eqBillMatcher("cc"))).andReturn(""); 

sut.doSomething("aa"); 

MATCH - 預期[AA],實際的[AA]

正如你所期望的。首場比賽命中。

sut.doSomething("cc"); 

不匹配 - 預期[AA],實際[CC]
不匹配 - 預期[AA],實際[CC]
MATCH - 預期[CC],則實際[CC]

每一個(包括已經通過的),直到它發現一個命中。

sut.doSomething("aa"); 

MATCH - 預期[AA],實際的[AA]
MATCH - 預期[AA],實際的[AA]

各自爲了直到發現有打之前沒有被調用過。

這將使它能夠提供意想不到的方法調用的」行中的錯誤消息,預計1,實際1(+1

-

代碼註釋 -

private boolean used = false; 

<snip/> 

public boolean matches(Object aActual) { 
    if (used) { 
    return false; 
    } 
    used = true; 
+0

我已經改變它使用createStrictMock(),因爲我想定義順序,但我並不期望得到這些MISMATCH行。 我比較的對象是相當完整的所以這就是爲什麼我在匹配器中有記錄器行。即使測試通過,我也會看到這些令人討厭的事情。 –

+0

抱歉要更清楚 - 我只想在發生測試失敗時看到我的消息。任何想法,如果這是可能的? –

+0

看着它被實現的方式(org.easymock.internal.ExpectedInvocation.matches) - 不,我不相信你可以。你可以讓BillMatcher變得更聰明(說在返回true後總是返回false),但這可能會混淆EasyMock。 (查看更新的消息) –