C# 使用Rhino Mock如何为模拟方法设置参数的属性

C# 使用Rhino Mock如何为模拟方法设置参数的属性,c#,unit-testing,syntax,mocking,rhino-mocks,C#,Unit Testing,Syntax,Mocking,Rhino Mocks,使用新的Rhino Mocks 3.5 Arrange/Act/Assert(AAA)测试风格,我在编写测试时遇到了问题 我有一个方法可以调用存储库类上的方法。ActivateFoo,其中我的Foo对象具有IsActive属性。ActivateFoo对象的结果应更改属性 以下是示例代码: [TestMethod] public void Should_update_foo_to_active_inside_of_repository() { // arrange var repo = M

使用新的Rhino Mocks 3.5 Arrange/Act/Assert(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();  
}
[TestMethod]
public void应在存储库()的内部将\u foo\u更新为\u active\u
{
//安排
var repo=MockRepository.GenerateMock();
var foo=new foo(){ID=1,IsActive=false};
var目标=新的提交人(回购);
回购预期(x=>x.ActivateFoo(foo)).Return(真);
//表演
目标。激活(foo);
//断言
Assert.IsTrue(foo.IsActive);
回购协议验证所有预期();
}
我猜关键的代码段应该介于“ActivateFoo(foo))”和“Return(true);”之间

有一点需要澄清的是,方法链接是如何在幕后工作的,如果有代码写在我期望的行上,那么它是在Return()之后还是之前重要吗?(当然,除非解决方案是使用Expect的MethodOptions重载或其他内容)


提前感谢您的帮助。

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


请让我知道它是否有效,如果无效,我可以使用它。

从外观上看,ActivateFoo应该是一种无效的方法。既然你是在模仿它,你就不应该验证它是否改变了你对象上的任何东西


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

您可能希望使用Do处理程序尝试类似的操作。我真的觉得Activatefo应该是无效的返回类型。但下面是使用bool返回类型激活tefo的代码

    [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;
    }
[TestMethod]
public void应在存储库()的内部将\u foo\u更新为\u active\u
{
//安排
var repo=MockRepository.GenerateMock();
var foo=new foo(){ID=1,IsActive=false};
var目标=新的提交人(回购);
回购预期(x=>x.ActivateFoo(foo))。
Do(新的ActivateFooDelegate(ActivateFooDelegateInstance));
//表演
目标。激活(foo);
//断言
Assert.IsTrue(foo.IsActive);
回购协议验证所有预期();
}
私人代表bool activatefodelegate(Foo f);
公共bool ActivateFooDelegateInstance(Foo f)
{
f、 IsActive=true;
返回f.IsActive;
}

多亏了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();
}
[TestMethod]
public void应在存储库()的内部将\u foo\u更新为\u active\u
{
//安排
var repo=MockRepository.GenerateMock();
var foo=new foo(){ID=1,IsActive=false};
var目标=新的提交人(回购);
回购预期(x=>x.ActivateFoo(foo))。
(新功能)(
委托(Foo f){f.IsActive=true;返回true;}
));
//表演
目标。激活(foo);
//断言
Assert.IsTrue(foo.IsActive);
回购协议验证所有预期();
}
我倾向于不需要为测试的一次使用提供额外的函数方法,如果可能的话,我更喜欢使用内联委托

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

所以,以后我可能不得不重构它并分离步骤,但现在,我已经让它工作了


谢谢

请澄清您的课程结构和关系。从你的例子来看,Foo和Presenter之间的关系不是很清楚。还可以在presenter中展开ActivateFoo(foo)&激活(foo)。