2010-12-06 9 views
2

私はユニットテストでモックオブジェクトの使用を検討してきましたが、.NET用のMoqフレームワークを試しています。私は、データベースからドメインオブジェクトを返すサービスレイヤメソッドをテストしようとする際にいくつか問題があります。ここでユニットテストでMoqを使用する際の問題

は私の設定です:ここでは

[SetUp] 
    public void DoSetupTasks() 
    { 
     mockDao = new Mock<IHibernateDao>(); 
     _hibernateService = new HibernateService(mockDao.Object); 
     mockDomainObject = new Mock<DomainBase>(); 
     dmBase = new DomainBase() 
     { 
      Id = 5 
     }; 
    } 

は私が問題を抱えていますユニットテストです。メソッドFindById()は、指定されたIDとタイプに基づいてDomainBaseオブジェクトを返します。私はユニットテストを実行すると

[Test] 
    public void TestFindById() 
    { 
     mockDomainObject.Setup(dmb => dmb.Id.Equals(It.IsAny<long>())).Returns(true); 
     mockDao.Setup(dao => dao.FindById(
      It.IsAny<long>(), 
      It.IsAny<Type>() 
     )).Returns(mockDomainObject.Object); 

     _hibernateService.FindById(dmb.Id, typeof(DomainBase)); 
     mockDomainObject.VerifySet(dmb => dmb.Id = dmBase.Id); 
    } 

、それは次の例外がスローされます。

Exception: Invalid setup on a non-virtual (overridable in VB) member: dmb => dmb.Id.Equals(It.IsAny<Int64>())

私は認めるよ、私はフレームワークとかなり慣れていないんです。私はそれについていくつかのチュートリアルに従おうとしてきましたが、私はそれを理解することができませんでした。

答えて

6

は、より多くのこのような何かを試してみてください:

[Test] 
public void TestFindById() { 

    const int TEST_ID = 5; 
    // Configure your mock DAO to return a real DomainBase 
    // when FindById is called. 
    mockDao 
     .Setup(dao => dao.FindById(TEST_ID, It.IsAny<Type>()) 
     .Returns(new DomainBase() { Id = TEST_ID }); 

    var domainObject = _hibernateService.FindById(TEST_ID , typeof(DomainBase)); 

    // Make sure the returned object is a DomainBase with id == TEST_ID 

    Assert.IsEqual(TEST_ID , domainObject.Id); 
    Assert.IsInstanceOf<DomainBase>(domainObject); 

    // and verify that your mock DAO was called with the same argument passed to 
    // your NHibernate service wrapper: 
    mockDao.VerifyAll(); 
} 

あなたのドメインオブジェクトをモックする必要はありません - あなたは、一般的にオフに優れている、あなたのデータ層とサービスをからかった後、実際のドメインオブジェクトを渡す(サンプルを含みます/テストデータ)を、テスト対象のロジックコードとモックされたサービスレイヤとの間で共有します。

EDIT:メソッドの保存と削除をテストするには、このようなことをしたいと思うでしょう。モックメソッドが呼び出されたときにMoqライブラリのCallback()メソッドを使用してコードを実行する方法に注意してください。このコールバックでは、メソッドに渡されたオブジェクトが期待していたオブジェクトであると主張しています。

[Test] 
public void TestSaveDomainBase() { 

    const int OBJECT_ID = 5; 

    mockDao 
     .Setup(dao => dao.Save(It.IsAny<DomainBase>())) 
     .Callback((DomainBase d) => { 
     // Make sure the object passed to Delete() was the correct one 
     Assert.AreEqual(OBJECT_ID, d.ID); 
     }); 

    var objectToSave = new DomainObject() { Id = OBJECT_ID }; 

    _hibernateService.Save(objectToDelete); 

    mockDao.VerifyAll(); 
} 


[Test] 
public void TestDeleteDomainBase() { 

    const int OBJECT_ID_TO_DELETE = 5; 

    mockDao 
     .Setup(dao => dao.Delete(It.IsAny<DomainBase>())) 
     .Callback((DomainBase d) => { 
     // Make sure the object passed to Delete() was the correct one 
     Assert.AreEqual(OBJECT_ID_TO_DELETE, d.ID); 
     }); 

    var objectToDelete = new DomainObject() { Id = OBJECT_ID_TO_DELETE }; 

    _hibernateService.Delete(objectToDelete); 


    mockDao.VerifyAll(); 
} 
+0

ありがとうございます!私はこれを打ち明けて、明日に戻ってきますが、ちょうどあなたのコードを見て、それはずっと今よりずっと意味があります。 –

+0

あなたの例は素晴らしい仕事でした。もう一度ありがとう、ディラン。もう1つの質問:ドメインオブジェクトのデータベースへの永続化またはオブジェクトの削除を検証するテストを作成するにはどうすればよいですか? –

+0

編集を参照してください。これはまったく同じ原理ですが、逆に、ドメインオブジェクトを作成してサービスメソッドに渡し、コールバックを介してサービスレイヤが適切なオブジェクトをDAOの正しいメソッドに渡していることを確認します。 –

関連する問題