3

次のコードがあります

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

registerNewRecord メソッドは RecordDao の insert メソッドを呼び出し、updateRecord は同じ DAO の update メソッドを呼び出します。

次のeasymockコードがあります:

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

問題は、上記で挿入された Record の同じインスタンスが更新されているため、insertRc Capture オブジェクトも更新されていることです。したがって、挿入時に終了フラグが false に設定されているとは断言できません。

私は何を間違っていますか?

4

3 に答える 3

3

insertRCとの両方の参照updateRCが同じオブジェクト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());
于 2009-12-17T17:14:55.520 に答える
2

1 つのアイデアは、キャプチャ時に 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テストしているコードが完了する前に、作成したオブジェクトを取得する方法はありません。キャプチャを使用すると、テスト中のメソッドが完了した後に、実行中に作成/取得されたオブジェクトについて質問することができます。

テストのもう 1 つの問題は、現在のメソッドのテストがregisterNewRecord()メソッド内のコードと、おそらく Record オブジェクトのコンストラクター内のコードに依存していることです。この依存関係を解消して Record オブジェクトの中間状態を検証する 1 つの方法は、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
}

良い副作用として、テストしているメソッドのコードに問題がある場合にのみテストが中断し、問題が Record のコンストラクタまたは registerNewRecord にある場合は中断しないことがわかります。registerNewRecord()ただし、メソッドが適切に機能することを確認するために、メソッドの 2 番目のテストを作成する必要があります。

于 2012-08-14T15:44:19.690 に答える