【问题标题】:Stub property setter with Rhino.Mocks to execute an action when called?带有 Rhino.Mocks 的存根属性设置器在调用时执行操作?
【发布时间】:2010-11-07 03:17:07
【问题描述】:

这可以通过以下方法完成:

myStub.Stub(x => x.SomeMethod()).WhenCalled(x => do something);

当调用属性设置器时,有什么方法可以做同样的事情吗?

【问题讨论】:

  • Jay,你有没有找到解决这个问题的 AAA 解决方案?

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


【解决方案1】:

以下将起作用:

Expect.Call(myStub.MyProperty).WhenCalled(p => Console.WriteLine("Called")).Return("Test result");

请注意,这仅在您的属性(在本例中为 MyProperty)被声明为虚拟时才有效。

【讨论】:

  • 谢谢,彼得。我还需要做什么才能使其正常工作?我总是使用 AAA 语法,所以我没有记录/重放的经验,如果是这样的话。当我以这种方式尝试时,我得到一个InvalidOperationException“当模拟对象处于重播状态时,此操作无效。”另外,我是否为本质上是void 方法(属性设置器)设置返回值?
  • 是的。您所做的如下: 1. 记录您的期望(如答案) 2. 调用 mocks.ReplayAll() 其中 mocks 是 MockRepository 的一个实例 3. 执行您的测试 4. 调用 mocks.VerifyAll()。当一个或多个期望没有得到满足时,最后一个将throw。如果你省略了最后一个调用,它不会检查。
【解决方案2】:

我手头没有 Visual Studio,但我确信这些方面的东西应该可以工作:

myStub.Stub(x => x.SomeProperty = null).WhenCalled(x => do something);

【讨论】:

  • 这正是我尝试过的,但它不起作用,即使在添加了 .IgnoreArguments() 之后也是如此。它编译并运行良好,但从未调用过 WhenCalled 表达式。
【解决方案3】:

将 mock 放回“记录”模式并使用旧的记录/播放语义来设置属性设置器的期望:

stub.BackToRecord();
Expect.Call(stub.SomeProperty).SetPropertyAndIgnoreArgument().WhenCalled(p => ...do something...);
stub.Replay();

【讨论】:

    【解决方案4】:

    所以 Pieter 和 Patrick 已经给出了正确的答案,但如果您喜欢开箱即用,一个更完整的示例可能会有所帮助。所以这里是:

    [Test]
    public void Test()
    {
        var fakedInterface = MockRepository.GenerateMock<ISite>();
    
        // Stub property setter and call own lambda when invoked.
        fakedInterface.BackToRecord();
        Expect.Call(fakedInterface.Name).SetPropertyAndIgnoreArgument().WhenCalled(a =>
        {
            Assert.That(a.Arguments.Length, Is.EqualTo(1));
            Assert.That(a.Arguments[0], Is.EqualTo("abc"));
    
            // Stub property getter with provided value.
            fakedInterface.Stub(x => x.Name).Return((String)a.Arguments[0]);
        });
        fakedInterface.Replay();
    
        // Set the property (and let our above lambda be invoked)
        fakedInterface.Name = "abc";
    
        // Get the property (the value that was freshly stubbed within the lamba.
        var result = fakedInterface.Name;
        Assert.That(result, Is.EqualTo("abc"));
    }
    

    本示例中的下一个技巧是,返回值将在 lambda 中存根,这样您就可以在 setter 中调用/测试任何您喜欢的内容,并且在下一步中您可以接收此值通过普通的属性获取器。

    【讨论】:

      【解决方案5】:

      我知道这有点老了,但所有的答案都有点不清楚。 从那时起,Ayende 已经放置了一个部分来处理这个问题,其中包含新旧结构,我认为如果我再次找到它可能会有所帮助。

      Rhino Mocks 3.5.

      已添加两个用于预期属性设置的构造。 以前使用 Rhino.Mocks 是可能的,但是已经有 流畅的接口语法中没有表现力的结构。

      具有特定值的属性设置期望被指定为 这个:

      Expect.Call(mockedCustomer.Name).SetPropertyWithArguments("Ayende");

      仅用于测试交互,属性设置期望 没有指定值是这样完成的:

      Expect.Call(mockedCustomer.Name).SetPropertyAndIgnoreArguments();

      这些新结构等于:

      使用(mocks.Record()) { mockedCustomer.Name = "Ayende"; //设置一个 期望设置一个特定的参数。

      LastCall.IgnoreArguments(); //我们可以忽略这个参数 期望,与让我们期望设置 财产,不考虑实际价值。 }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-05
        • 2016-10-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-15
        • 2011-11-30
        相关资源
        最近更新 更多