使用Rhino Mocks,为什么在测试初始化​​期间调用属性上的模拟会返回预期的调用#1,实际调用#0?

时间:2022-04-16 21:07:27

I currently have a test which tests the presenter I have in the MVP model. On my presenter I have a property which will call into my View, which in my test is mocked out. In the Initialization of my test, after I set my View on the Presenter to be the mocked View, I set my property on the Presenter which will call this method.

我目前有一个测试,测试我在MVP模型中的演示者。在我的主持人身上,我有一个属性,可以调用我的视图,在我的测试中被嘲笑。在我的测试的初始化中,在我将Presenter上的View设置为模拟视图后,我在Presenter上设置我的属性,该属性将调用此方法。

In my test I do not have an Expect.Call for the method I invoke, yet when I run I get this Rhino mock exception:

在我的测试中,我没有为我调用的方法使用Expect.Call,但是当我运行时,我得到了这个Rhino模拟异常:

Rhino.Mocks.Exceptions.ExpectationViolationException: IView.MethodToInvoke(); Expected #1, Actual #0..

Rhino.Mocks.Exceptions.ExpectationViolationException:IView.MethodToInvoke();预计#1,实际#0 ..

From what I understand with Rhino mocks, as long as I am invoking on the Mock outside the expecting block it should not be recording this. I would imagine the test to pass. Is there a reason it is not passing?

根据我对Rhino模拟的理解,只要我在预期的块外面调用模拟它就不应该记录这个。我想象测试通过。有没有理由不通过?

Below is some code to show my setup.

下面是一些显示我的设置的代码。

public class Presenter
{
    public IView View;

    public Presenter(IView view)
    {
        View = view
    }
    private int _property;
    public int Property
    get { return _property;}
    set
    {
       _property = value;

       View.MethodToInvoke();
    }
}

... Test Code Below ...

......下面的测试代码......

[TestInitialize]
        public void Initilize()
        {
            _mocks = new MockRepository();
            _view = _mocks.StrictMock<IView>();
            _presenter = new Presenter(_view);
            _presenter.Property = 1;            
        }
[TestMethod]
        public void Test()
        {
            Rhino.Mocks.With.Mocks(_mocks).Expecting(delegate
            {                
            }).Verify(delegate
            {
                _presenter.SomeOtherMethod();
});
        }

3 个解决方案

#1


Why in the world would you want to test the same thing each time a test is run?

为什么在世界上你想在每次测试运行时测试相同的东西?

If you want to test that a specific thing happens, you should check that in a single test.

如果您想测试特定的事情发生,您应该在一次测试中检查。

The pattern you are using now implies that you need to - set up prerequisites for testing - do behavior - check that behavior is correct and then repeat that several times in one test

您现在使用的模式意味着您需要 - 设置测试的先决条件 - 执行行为 - 检查行为是否正确,然后在一次测试中重复多次

You need to start testing one thing for each test, and that help make the tests clearer, and make it easier to use the AAA syntax.

您需要为每个测试开始测试一件事,这有助于使测试更清晰,并且更容易使用AAA语法。

There's several things to discuss here, but it certainly would be clearer if you did it something like:

这里有几件事要讨论,但如果你这样做的话肯定会更清楚:

[TestMethod]
ShouldCallInvokedMethodWhenSettingProperty()
{
   var viewMock = MockRepository.GenerateMock<IView>()

   var presenter = new Presenter(viewMock);

   presenter.Property = 1;

   viewMock.AssertWasCalled(view => view.InvokedMethod());

}

Read up more on Rhino Mocks 3.5 syntax here: http://ayende.com/Wiki/Rhino+Mocks+3.5.ashx

阅读更多关于Rhino Mocks 3.5语法的信息:http://ayende.com/Wiki/Rhino+Mocks+3.5.ashx

#2


  1. What exactly are you trying to test in the Test method?
  2. 你究竟想在Test方法中测试什么?

  3. You should try to avoid using strict mocks.
  4. 你应该尽量避免使用严格的模拟。

  5. I suggest using the Rhino's AAA syntax (Arrange, Act, Assert).
  6. 我建议使用Rhino的AAA语法(Arrange,Act,Assert)。

#3


The problem lied with me not understanding the record/verify that is going on with Strict mocks. In order to fix the issue I was having this is how I changed my TestInitilize function. This basicaly does a quick test on my intial state I'm setting up for all my tests.

问题在于我不理解Strict模拟正在进行的记录/验证。为了解决这个问题我正在改变我的TestInitilize函数。这基本上对我的初始状态进行了快速测试,我正在为我的所有测试进行设置。

[TestInitialize]
    public void Initilize()
    {
        _mocks = new MockRepository();
        _view = _mocks.StrictMock<IView>();
        _presenter = new Presenter(_view);

        Expect.Call(delegate { _presenter.View.InvokedMethod(); });
        _mocks.ReplayAll();
        _mocks.VerifyAll();
        _mocks.BackToRecordAll();
        _presenter.Property = 1;
    }

#1


Why in the world would you want to test the same thing each time a test is run?

为什么在世界上你想在每次测试运行时测试相同的东西?

If you want to test that a specific thing happens, you should check that in a single test.

如果您想测试特定的事情发生,您应该在一次测试中检查。

The pattern you are using now implies that you need to - set up prerequisites for testing - do behavior - check that behavior is correct and then repeat that several times in one test

您现在使用的模式意味着您需要 - 设置测试的先决条件 - 执行行为 - 检查行为是否正确,然后在一次测试中重复多次

You need to start testing one thing for each test, and that help make the tests clearer, and make it easier to use the AAA syntax.

您需要为每个测试开始测试一件事,这有助于使测试更清晰,并且更容易使用AAA语法。

There's several things to discuss here, but it certainly would be clearer if you did it something like:

这里有几件事要讨论,但如果你这样做的话肯定会更清楚:

[TestMethod]
ShouldCallInvokedMethodWhenSettingProperty()
{
   var viewMock = MockRepository.GenerateMock<IView>()

   var presenter = new Presenter(viewMock);

   presenter.Property = 1;

   viewMock.AssertWasCalled(view => view.InvokedMethod());

}

Read up more on Rhino Mocks 3.5 syntax here: http://ayende.com/Wiki/Rhino+Mocks+3.5.ashx

阅读更多关于Rhino Mocks 3.5语法的信息:http://ayende.com/Wiki/Rhino+Mocks+3.5.ashx

#2


  1. What exactly are you trying to test in the Test method?
  2. 你究竟想在Test方法中测试什么?

  3. You should try to avoid using strict mocks.
  4. 你应该尽量避免使用严格的模拟。

  5. I suggest using the Rhino's AAA syntax (Arrange, Act, Assert).
  6. 我建议使用Rhino的AAA语法(Arrange,Act,Assert)。

#3


The problem lied with me not understanding the record/verify that is going on with Strict mocks. In order to fix the issue I was having this is how I changed my TestInitilize function. This basicaly does a quick test on my intial state I'm setting up for all my tests.

问题在于我不理解Strict模拟正在进行的记录/验证。为了解决这个问题我正在改变我的TestInitilize函数。这基本上对我的初始状态进行了快速测试,我正在为我的所有测试进行设置。

[TestInitialize]
    public void Initilize()
    {
        _mocks = new MockRepository();
        _view = _mocks.StrictMock<IView>();
        _presenter = new Presenter(_view);

        Expect.Call(delegate { _presenter.View.InvokedMethod(); });
        _mocks.ReplayAll();
        _mocks.VerifyAll();
        _mocks.BackToRecordAll();
        _presenter.Property = 1;
    }