2010-02-02 64 views
6

是否可以模擬存根/模擬的對象成員調用而不必將其定義爲存根,並將返回值設置爲所有單獨的詳細行?犀牛可以直接模擬深層/嵌套成員嗎?

例子:

[TestMethod] 
    public void AssignedPermissions_AssociateExists_ReturnsEdit_Rhino() 
    { 

     //Arrange 
     var fakeConfiguration = MockRepository.GenerateStub<IDomainControllerConfiguration>(); 
     var fakeAssociateRepository = MockRepository.GenerateStub<IAssociateRepository>(); 
     fakeConfiguration.Stub(x => x.AssociateRepository).Return(fakeAssociateRepository); 
     fakeAssociateRepository.Stub(x=>x.GetAssociatesByRole(null,false,null)).IgnoreArguments() 
      .Return(new IAssociate[]{MockRepository.GenerateStub<IAssociate>()}); 

     var domain = new DomainController(fakeConfiguration); 

     const AssignedPermission expected = AssignedPermission.Edit; 

     //Act 
     AssignedPermission actual = domain.AssignedPermissions(); 

     //Assert 
     Assert.AreEqual(expected, actual); 
    } 

是否需要所有這些臨時變量只是存根出嵌套的方法調用?

+0

你碰上違反迪米特法則的後果之一:http://clintshank.javadevelopersjournal.com/long_unit_test_setup。 htm – 2010-02-03 10:58:20

+0

@wcoenen好..配置對象不應該直接處理內部調用者我會想嗎?所以至少這一層嵌套似乎很重要或有價值。因爲這通常只是一個裸DTO – Maslow 2010-02-03 13:40:06

+0

您不一定必須在配置對象上添加傳遞方法。爲什麼不爲存儲庫添加構造函數參數? '新的DomainController(fakeConfiguration,fakeRepository);' – 2010-02-03 14:53:22

回答

3

我從來沒有使用過這個功能,所以我不能100%確定這會起作用,但理論上Rhino mocks支持「recursive mocking」,它應該允許你通過做這樣的事情來至少切斷fakeAssociateRepository :

var fakeConfiguration = MockRepository.GenerateStub<IDomainControllerConfiguration>(); 
fakeConfiguration.Stub(x => x.AssociateRepository.GetAssociatesByRole(null,false,null)) 
      .IgnoreArguments() 
      .Return(new IAssociate[]{MockRepository.GenerateStub<IAssociate>()}); 

var domain = new DomainController(fakeConfiguration); 

(注:代碼沒有測試,甚至編譯)