3

MS SQL ServerデータベースでC#とLinq2SQLを使用します。いくつかのユニットテストを実行するためのmockdatacontextがあります。テストの結果、「実際の」データベースと「モック」データベースのどちらが使用されているかに応じて、2つの異なる動作が見つかりました。

シナリオ1:実際のデータベース

データベースには5つのレコードがあります。

db = realDatabase
db.InsertOnSubmit(new record)

var count1 = db.getTable.Count()

db.SubmitChanges()

var count2 = db.getTable.Count()

count1 = 5 count2 = 6

シナリオ2:モックデータベース

データベースには5つのレコードがあります。

db= mockDatabase

db.InsertOnSubmit(new record)

var count1 = db.getTable.Count()

db.SubmitChanges()

var count2 = db.getTable.Count()

count1 = 6 count2 = 6

*「モック」データベースは、SubmitChanges()が呼び出される前に新しいレコードをすでに認識しているため、カウントに含まれます。テストでは、2つの動作が同じである必要があります。

他の誰かがこの問題に遭遇しましたか、そしてあなたは解決策を提案できますか?

4

2 に答える 2

7

IMO、テストでシミュレートしようとするのはよくある間違いです。モックはシミュレーターではありません。オリジナルと同様のロジックを実装するべきではなく、ハードコーディングされた結果を返すだけです。

モックの動作が複雑な場合、ビジネス コードではなくモックをテストすることになります。

私は RhinoMocks を使用していますが、次のようになります。

// arrange
IList<Record> testdata = new List<Record>() {a, b, c};
db = MockRepository.GenerateMock<IDatabase>();
db.Stub(x => db.getTable).Return(testdata);

// act: call your unit under test

// assert
db.AssertWasCalled(x => x.InsertOnSubmit(Arg<Record>.Is.Anything));
db.AssertWasCalled(x => x.SubmitChanges());

毎回同じリストを返します。多くの場合、これで十分です。2 番目の getTable 呼び出しで他のデータを返すこともできます。

db.Stub(x => db.getTable).Return(testdata1);
db.Stub(x => db.getTable).Return(testdata2);

常に単一のテストに固有ですが、これにより非常に簡単になります。

編集:

私は Linq2Sql に慣れていないことを認めざるを得ません。私の例でモックされている呼び出しは Linq2Sql 呼び出しであり、おそらくそれほど簡単にモックすることはできません。おそらく、単純な DAL インターフェイスの背後に配置する必要があります。次に、このインターフェイスをモックします。

于 2009-04-29T22:20:14.340 に答える
0

InsertOnSubmitあなたのモックデータベース(メモリ内??)はトランザクションではなく、メソッドが実際にレコードを挿入していると思います。

于 2009-04-29T18:39:20.237 に答える