使用Rhino Mocks如何为Mocked方法设置参数的属性

时间:2009-03-11 17:08:04

标签: c# unit-testing syntax mocking rhino-mocks

使用新的Rhino Mocks 3.5安排/动作/断言(AAA)测试风格,我在编写测试时遇到了问题。

我有一个方法可以调用存储库类的方法。 ActivateFoo,我的Foo对象具有IsActive属性。 ActivateFoo对象的结果应该更改属性。

以下是示例代码:

[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
  // arrange
  var repo = MockRepository.GenerateMock<IRepository>();
  var foo = new Foo() { ID = 1, IsActive = false };
  var target = new Presenter(repo);
  repo.Expect(x => x.ActivateFoo(foo)).Return(true);

  // act
  target.Activate(foo);

  // assert
  Assert.IsTrue(foo.IsActive);
  repo.VerifyAllExpectations();  
}

我猜测代码的关键部分是“ActivateFoo(foo)”。“和“返回(真实);”。

有一点是为了澄清方法链接在幕后工作的方法,如果在我预期的行上写了代码,那么它是否在Return()之后或之前是否重要? (当然,除非解决方案是使用Expect的MethodOptions重载或其他东西)。

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

感谢AB Kolan,这是我使用和生效的代码。

[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
    // arrange
    var repo = MockRepository.GenerateMock<IRepository>();
    var foo = new Foo() { ID = 1, IsActive = false };
    var target = new Presenter(repo);
    repo.Expect(x => x.ActivateFoo(foo)).
        Do(new Func<Foo, bool>(
            delegate(Foo f) { f.IsActive = true; return true; }
        ));

    // act
    target.Activate(foo);

    // assert
    Assert.IsTrue(foo.IsActive);
    repo.VerifyAllExpectations();
}

我倾向于不喜欢单独使用测试的额外函数方法,如果可能的话,更喜欢内联委托。

为了解决这个问题,我应该做的事与设计有关。由于名称存在,这不是target.Activate()方法的确切代码。 Activate()中的代码执行一些检查,如果需要,将执行存储库ActivateFoo(),然后检查该操作的结果并执行其他操作。

所以,稍后我可能需要重构这个并将步骤分开,但是现在,我已经让它工作了。

由于

答案 1 :(得分:0)

我还没有真正使用这个版本的RhinoMocks,但在旧版本中你必须使用.Do(适当的委托)来设置标志并返回值(而不是.Return)。

请告诉我它是否有效,如果不能,我可以随意使用它。

答案 2 :(得分:0)

从它的外观来看,ActivateFoo应该是一个void方法。既然你在嘲笑它,你就不应该验证它会改变你对象的任何东西。

在测试存储库方法ActivateFoo时,您将验证IsActive属性是否已更改,而不是在演示者上测试Activate方法时。

答案 3 :(得分:0)

你可能想要使用Do处理程序尝试这样的东西。我老实说觉得ActivateFoo应该是无效的返回类型。但这是使用bool返回类型的ActivateFoo的代码。

    [TestMethod]
    public void Should_update_foo_to_active_inside_of_repository()
    {
        // arrange
        var repo = MockRepository.GenerateMock<IRepository>();
        var foo = new Foo() { ID = 1, IsActive = false };
        var target = new Presenter(repo);
        repo.Expect(x => x.ActivateFoo(foo)).
            Do(new ActivateFooDelegate(ActivateFooDelegateInstance));
        // act
        target.Activate(foo);

        // assert
        Assert.IsTrue(foo.IsActive);
        repo.VerifyAllExpectations();
    }

    private delegate bool ActivateFooDelegate(Foo f);

    public bool ActivateFooDelegateInstance(Foo f)
    {
        f.IsActive = true;
        return f.IsActive;
    }