【问题标题】:Can Rhino Mock deeper/nested members directly?Rhino 可以直接模拟更深/嵌套的成员吗?
【发布时间】:2010-02-02 21:35:23
【问题描述】:

是否可以模拟存根/模拟的对象成员调用而不必将其定义为存根,并将返回值设置为所有单独的详细行?

例子:

    [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);
    }

是否所有这些临时变量都只需要存根嵌套的方法调用?

【问题讨论】:

  • 你遇到了违反得墨忒耳法则的后果之一:clintshank.javadevelopersjournal.com/long_unit_test_setup.htm
  • @wcoenen 好吧.. 配置对象不应该真正直接处理调用者内部我认为的内容?因此,至少这一层嵌套似乎很重要或有价值。因为这主要是一个裸露的 DTO
  • 您不一定要在配置对象上添加传递方法。为什么不为存储库添加一个构造函数参数? new DomainController(fakeConfiguration, fakeRepository);

标签: unit-testing rhino-mocks


【解决方案1】:

我从来没有使用过这个功能,所以我不能 100% 确定这会起作用,但理论上 Rhino 模拟支持“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);

(注意:代码未经测试,甚至未编译)

【讨论】:

    【解决方案2】:

    只是想分享我对此的看法,因为我最近几个小时都在努力解决这个问题。 Alconja 上面发布的答案绝对有效,但如果您打算将它用于“AssertWasCalled”类型的断言,它不会按照我期望的方式断言。似乎 AssertWasCalled 方法试图断言与“嵌套”对象关联的“获取访问器”。

    例如,如果您想这样做:

    fakeconfiguration.AssertWasCalled(x => x.AssociateRepository.GetAssociatesByRole(null, false, null));
    

    你会得到一个例外,比如

    System.InvalidOperationException : Previous method 'IDomainControllerConfiguration.get_AssociateRepository();' requires a return value or an exception to throw.
    

    因为 AssertWasCalled 断言的是 AssociateRepository 属性的 get-accessor,而不是 GetAssociatesByRole() 方法。最后,就我而言,我不得不使用 OP 的方法来创建多个存根。

    【讨论】:

      猜你喜欢
      • 2020-01-20
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多