3

我有以下代码

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 插入的同一 Record 实例正在更新,insertRc Capture 对象也正在更新。所以我不能断言完成标志在插入时设置为假。

我究竟做错了什么?

4

3 回答 3

3

如果 和 中的引用insertRCupdateRC引用同一个对象rd,并且在方法期间更改了 this update,您将始终看到该Record对象已完成。但是,您可以在调用之前测试第一个 Captured 对象update

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());
于 2009-12-17T17:14:55.520 回答
2

一种想法是在捕获 Record 对象时对其进行克隆。

在 Record 类中实现一个clone()方法,然后实现一个自定义 Capture,如下所示:

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 类可以只在方法中提取它需要的信息(即 Record finished 标志)setValue并存储它。

于 2009-12-02T23:20:39.970 回答
0

捕获不是答案。问题是您的代码正在 registerNewRecord 中创建一个新对象(或者我认为如此)。new在您正在测试的代码完成之前,无法获取您创建的对象。捕获允许您在被测方法完成后询问在执行期间创建/获得的对象的问题。

您的测试的另一个问题是您对当前方法的测试取决于方法中的代码,registerNewRecord()并且可能是 Record 对象的构造函数中的任何代码。打破这种依赖关系并验证 Record 对象的中间状态的一种方法是存根该registerNewRecord()方法并让它返回一个模拟。然后,您可以测试是否对 Record 对象进行了正确的调用,并且您的代码对于来自 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
}

作为一个积极的副作用,您会发现您的测试仅在您正在测试的方法中的代码出现问题时才会中断,而如果问题在于 Record 的构造函数或 registerNewRecord,则永远不会中断。但是,您将希望为该registerNewRecord()方法编写第二个测试以确保其正常工作。

于 2012-08-14T15:44:19.690 回答