2009-12-01 70 views
3

測試有以下代碼如何與EasyMock的捕捉

Record rd = registerNewRecord(); 
<do some processing> 
rd.setFinished(true); 
updateRecord(rd); 

的registerNewRecord方法調用RecordDao插入方法,和updateRecord呼籲同DAO的更新方法。

我有以下EasyMock的代碼:

Capture<Record> insertRc = new Capture<Record>(); 
RecordDao.insert(capture(insertRc)); 
Capture<Record> updateRc= new Capture<Record>(); 
RecordDao.update(capture(updateRc)); 

問題是因爲上述RD已插入記錄的同一實例正被更新時,insertRc捕捉對象被太更新。所以我不能斷言完成標誌在插入時被設置爲false。

我在做什麼錯了?

回答

1

一個想法是在捕獲它時克隆Record對象。

實現你的記錄類clone()方法,然後實現自定義捕獲如下:

public class RecordCloneCapture extends Capture<Record> { 
    @Override 
    public void setValue(Record value) { 
     super.setValue(value == null ? null : value.clone()); 
    } 
} 

,改變你的測試代碼使用它:

Capture<Record> insertRc = new RecordCloneCapture(); 
RecordDao.insert(capture(insertRc)); 
Capture<Record> updateRc= new RecordCloneCapture(); 
RecordDao.update(capture(updateRc)); 

如果你不能由於某種原因實施clone(),您的自定義Capture類可以在setValue方法中提取它需要的信息(即記錄完成標誌)並存儲它。

3

如果內insertRCupdateRC兩個引用指向同一個對象rd,這是update方法中被改變,你總會看到Record對象已完成。但是,您可以在調用update之前測試第一個Captured對象。

Capture<Record> insertRc = new Capture<Record>(); 
RecordDao.insert(capture(insertRc)); 
Record insertedRecord = insertRC.getValue(); 
org.junit.Assert.assertFalse(insertedRecord.isFinished()); 

Capture<Record> updateRc= new Capture<Record>(); 
RecordDao.update(capture(updateRc)); 
Record updatedRecord = updateRC.getValue(); 
org.junit.Assert.assertTrue(updatedRecord.isFinished()); 
0

捕獲不是答案。問題是你的代碼是在registerNewRecord中創建一個新的對象(或者我假設)。在您正在測試的代碼完成之前,無法使用new獲取您創建的對象。捕獲允許您在執行過程中提出創建/獲取的對象的問題,然後完成待測試的方法。

測試的另一個問題是,您對當前方法的測試取決於registerNewRecord()方法中的代碼,並且可能是Record對象構造函數中的任何代碼。破壞這種依賴關係並驗證Record對象的中間狀態的一種方法是將registerNewRecord()方法取出並讓它返回一個模擬。然後,您可以測試是否對Record對象進行了正確的調用,並且您的代碼對於來自記錄對象的所有可能的返回值都是正確的。

MyClassStub extends MyClass { 
    Record registerNewRecord() { 
    return recordMock; 
    } 
} 

MyClass objectToTest = new MyClassStub(); 

public void testSomeMethod() { 
    // set expectations, call replay 
    objectToTest.someMethod(); // (contains above code that calls registerRecord) 
    // asserts/verify 
} 

作爲一個積極的副作用,你會發現,你的測試只休息時,有什麼問題你要測試的方法的代碼,從不如果問題出在記錄的構造函數或registerNewRecord打破。然而,您將要爲registerNewRecord()方法編寫第二個測試,以確保其正常工作。