1

私は、持続性の無知を尊重しようと積極的に取り組んでいる新しいプロジェクトに取り組んでいます。例として、私のサービス レイヤーでは、ORM からエンティティを取得し、エンティティに変更を加える場合としない場合があるエンティティで定義されたルーチンを呼び出します。次に、ORM に依存して、エンティティが変更されたかどうかを検出し、必要な挿入/更新/削除を行います。

アプリケーションを実行すると、意図したとおりに動作し、これが実際に動作しているのを見るのは本当に素晴らしいことです。私のビジネス ロジックは非常に分離されており、私のサービス レイヤーは非常に薄いです。

もちろん、今は単体テストを追加していますが、特定のプロパティが変更されたかどうかを検証する単体テストを記述できないことに気付きました。以前のソリューションでは、オブジェクトが期待される状態でリポジトリ呼び出しが行われたかどうかを判断しました。

mockRepository.Verify(mr => 
  mr.SaveOrUpdate(It.Is<MyEntity>(x => 
    x.Id == 123 && x.MyProp == "newvalue")), Times.Once());

持続性の無知に正しく近づいていますか? リポジトリの保存メソッドを明示的に呼び出さない場合に、エンティティの操作後の状態を単体テストするより良い方法はありますか?

それが役立つ場合、私は ASP.NET MVC 3、WCF、NHibernate、および NUnit/Moq を使用しています。単体テストは、サービス クラスのインスタンスを渡すコントローラー アクションを呼び出します (モック リポジトリでインスタンス化されます)。

4

2 に答える 2

0

奇妙なことに、私は解決策に出くわしました、そしてそれは本当に簡単です。

[Test]
public void Verify_Widget_Description_Is_Updated()
{
  // arrange
  var widget = new Widget { };
  mockWidgetRepo.Setup(mr => mr.GetWidget()).returns(widget);

  var viewModel = new WidgetVM { };
  viewModel.Description = "New Desc";  

  // act
  var result = (ViewResult)controller.UpdateWidget(viewModel);

  // assert
  Assert.AreEqual("New Desc", widget.Description);
}

完璧ではありませんが、widget.Descriptionがビューモデルに割り当てた値と一致する場合、evictが呼び出されない限り、ORMはその変更を保存すると想定できます。

更新: 別の代替ソリューションを思いついたところです。ベースリポジトリにObjectStateAssertionForTests(Object obj)関数を作成しましたが、これは何もしません。この関数をコードで呼び出してから、単体テストで確認できます。

mockRepository.Verify(mr => 
  mr.ObjectStateAssertionForTests(It.Is<MyEntity>(x => 
    x.Id == 123 && x.MyProp == "newvalue")), Times.Once());
于 2011-10-25T18:19:27.363 に答える
0

リポジトリを表すインターフェイスがあり、テストで偽物を渡すという点で、これに正しく取り組んでいます。スタブ実装がテストを作成する傾向があるため、モックを使用する代わりに、リポジトリにインメモリ シミュレータを使用することを好みます。モック/検証を使用するよりも脆弱ではありません (上記のリンクのモックはスタブではありません)。リポジトリに Add/Find/Delete メソッドがある場合、メモリ内実装はそれらをメンバー リストに転送し、保存すると、テストでアサートできる SavedList というプロパティが設定されます。

于 2011-07-06T03:06:13.180 に答える