2010-02-02 70 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); 

(注:代码没有测试,甚至编译)