简体   繁体   English

犀牛嘲笑部分模拟

[英]Rhino Mocks Partial Mock

I am trying to test the logic from some existing classes. 我试图从一些现有的类测试逻辑。 It is not possible to re-factor the classes at present as they are very complex and in production. 由于它们非常复杂并且在生产中,因此不可能重新考虑目前的类别。

What I want to do is create a mock object and test a method that internally calls another method that is very hard to mock. 我想要做的是创建一个模拟对象并测试一个内部调用另一个非常难以模拟的方法的方法。

So I want to just set a behaviour for the secondary method call. 所以我想为次要方法调用设置一个行为。

But when I setup the behaviour for the method, the code of the method is invoked and fails. 但是当我设置方法的行为时,方法的代码被调用并失败。

Am I missing something or is this just not possible to test without re-factoring the class? 我是否遗漏了某些东西,或者这是不可能在没有重新分类的情况下进行测试?

I have tried all the different mock types (Strick,Stub,Dynamic,Partial ect.) but they all end up calling the method when I try to set up the behaviour. 我已经尝试了所有不同的模拟类型(Strick,Stub,Dynamic,Partial等),但是当我尝试设置行为时,它们都会调用该方法。

using System;
using MbUnit.Framework;
using Rhino.Mocks;

namespace MMBusinessObjects.Tests
{
    [TestFixture]
    public class PartialMockExampleFixture
    {
        [Test]
        public void Simple_Partial_Mock_Test()
        {
            const string param = "anything";

            //setup mocks
            MockRepository mocks = new MockRepository();


            var mockTestClass = mocks.StrictMock<TestClass>();

            //record beahviour *** actualy call into the real method stub ***
            Expect.Call(mockTestClass.MethodToMock(param)).Return(true);

            //never get to here
            mocks.ReplayAll();

            //this is what i want to test
            Assert.IsTrue(mockTestClass.MethodIWantToTest(param));


        }

        public class TestClass
        {
            public bool MethodToMock(string param)
            {
                //some logic that is very hard to mock
                throw new NotImplementedException();
            }

            public bool MethodIWantToTest(string param)
            {
                //this method calls the 
                if( MethodToMock(param) )
                {
                    //some logic i want to test
                }

                return true;
            }
        }
    }
}

MethodToMock is not virtual and therefore can't be mocked. MethodToMock不是虚拟的,因此无法模拟。 What you want to do is possible with a partial mock (I've done it in cases similar to yours), but the method you want to mock out must be either part of an interface implementation or be marked virtual. 您想要做的是使用部分模拟(我在类似于您的情况下完成它),但您想要模拟的方法必须是接口实现的一部分或标记为虚拟。 Otherwise, you can't mock it with Rhino.Mocks. 否则,您无法使用Rhino.Mocks进行模拟。

I recommend not mocking methods in the class under test, but your situation may be unique in that you can't refactor the class to make it easier to test at present. 我建议不要在被测试的类中模拟方法,但是你的情况可能是独特的,因为你不能重构类以使其更容易测试。 You might try explicitly making a delegate to prevent the method from being invoked when setting up the call. 您可以尝试显式创建委托以防止在设置调用时调用该方法。

 Expect.Call( delegate { mockTestClass.MethodToMock(param) } ).Return(true);

Or, switch to using the AAA syntax, omitting the deprecated constructs. 或者,切换到使用AAA语法,省略不推荐使用的构造。

    [Test]
    public void Simple_Partial_Mock_Test()
    {
        const string param = "anything";

        var mockTestClass = MockRepository.GenerateMock<TestClass>();

        mockTestClass.Expect( m => m.MethodToMock(param) ).Return( true );

        //this is what i want to test
        Assert.IsTrue(mockTestClass.MethodIWantToTest(param));

        mockTestClass.VerifyAllExpectations();
    }

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

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