简体   繁体   English

如何正确使用Rhino.Mocks AssertWasCalled()?

[英]How to use Rhino.Mocks AssertWasCalled() correctly?

I call _mocks.ReplayAll() , then one or more _mockedObject.AssertWasCalled() and then _mocks.VerifyAll() . 我调用_mocks.ReplayAll() ,然后调用一个或多个_mockedObject.AssertWasCalled() ,然后_mocks.VerifyAll() But it tells me that "This action is invalid when the mock object is in record state". 但它告诉我“当模拟对象处于记录状态时,此操作无效”。

[Test]
public void SetStateExecuting_Should_Set_State_To_Pause_And_Not_Change_GlobalState_When_GlobalState_Is_Paused()
{
    var task = new Task { ID = 1, TimeZone = -660, GlobalState = TaskState.Paused };
    _taskDataProvider.Expect(p => p.StateUpdate(task.ID, task.TimeZone, TaskState.Paused));
    _mockRepository.ReplayAll();
    _manager.SetStateExecuting(task);
    _taskDataProvider.AssertWasNotCalled(p => p.GlobalStateUpdate(task.ID, 
                                                                  TaskState.Executing));
    _mockRepository.VerifyAll();
}

What is the correct order to call so that these methods work correctly? 调用正确的顺序是什么,以便这些方法正常工作?

Jon Kruger's blog post "How to use rhino mocks documented through tests" has simple examples of everything you can do with rhino mocks methods. Jon Kruger的博客文章“如何使用通过测试记录的犀牛模拟”有一些简单的例子,说明了使用rhino模拟方法可以做的一切。 He also shows what you can not do which I found very helpful in learning. 他还展示了你不能做的事情,我觉得这对学习非常有帮助。

As mentioned before, using the Arrange, Act, Assert Syntax with the static constructors is easier to read. 如前所述,使用Arrange,Act,Assert语法和静态构造函数更容易阅读。 The blog post shows examples of both methods. 博客文章显示了这两种方法的示例。

Here are examples from Jon's sample code: 以下是Jon的示例代码示例:

New syntax: 新语法:

 [Test]
    public void You_can_check_to_see_if_a_method_was_called()
    {
        var stub = MockRepository.GenerateStub<ISampleClass>();

        stub.MethodThatReturnsInteger("foo");

        stub.AssertWasCalled(s => s.MethodThatReturnsInteger("foo"));
        stub.AssertWasCalled(s => s.MethodThatReturnsInteger(Arg<string>.Is.Anything));
    }

Old style: 老式:

    [Test]
    public void Calling_virtual_methods_will_call_the_actual_method()
    {
        var mockRepository = new MockRepository();
        var sampleClass = mockRepository.PartialMock<SampleClass>();
        sampleClass.Replay();

        sampleClass.VirtualMethod("foo").ShouldEqual(3);
        sampleClass.VirtualMethodWasCalled.ShouldBeTrue();
        sampleClass.AssertWasCalled(c => c.VirtualMethod("foo"));
    }

You are mixing the old Record/Replay pattern and the new AAA pattern . 您正在混合旧的记录/重放模式和新的AAA模式

The normal way to set up a "not called with these arguments" expectation while in Record mode looks like this: 在记录模式下设置“未使用这些参数调用”的常规方法如下所示:

_taskDataProvider.Expect(
    p => p.GlobalStateUpdate(task.ID, TaskState.Executing)).Repeat.Never();

Or alternatively, you can use a strict mock which simply doesn't allow unexpected calls. 或者,您可以使用严格模拟,但不允许意外调用。

AssertWasCalled and AssertWasNotCalled are intended for AAA where you put your assertions at the end. AssertWasCalledAssertWasNotCalled适用于AAA,您可以将断言放在最后。 With the Record/Replay syntax, both behavior and expecations should be set up at the start before the switch to replay mode. 使用Record / Replay语法,应在切换到重放模式之前的开始处设置行为和expecations。

( AssertWasNotCalled might actually work with Record/Replay also, but I never tried it because I don't like to mix elements from both approaches. It needlessly complicates things.) AssertWasNotCalled也可以实际使用Record / Replay,但我从未尝试过,因为我不喜欢混合两种方法中的元素。这不必要地使事情变得复杂。)

Seems like I found the solution. 好像我找到了解决方案。 It's seems a bit weird, but it works. 这看起来有点奇怪,但它确实有效。 It turns out that I need to call ReplayAll() twice for some reason... 事实证明,由于某种原因,我需要两次调用ReplayAll()...

This works: 这有效:

[Test]
public void SetStateExecuting_Should_Set_State_To_Pause_And_Not_Change_GlobalState_When_GlobalState_Is_Paused()
{
    var task = new Task { ID = 1, TimeZone = -660, GlobalState = TaskState.Paused };
    _mockRepository.ReplayAll();
    _manager.SetStateExecuting(task);
    _taskDataProvider.AssertWasCalled(p => p.StateUpdate(task.ID, task.TimeZone, TaskState.Paused));
    _taskDataProvider.AssertWasNotCalled(p => p.GlobalStateUpdate(task.ID, TaskState.Executing));
    _mockRepository.ReplayAll();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM