犀牛嘲笑部分模拟

时间:2010-05-04 11:41:29

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

我正在尝试从一些现有的类中测试逻辑。目前无法对课程进行重新分解,因为它们非常复杂并且正在制作中。

我想要做的是创建一个模拟对象并测试一个内部调用另一个非常难以模拟的方法的方法。

所以我想为次要方法调用设置一个行为。

但是当我设置方法的行为时,方法的代码被调用并失败。

我是否遗漏了某些内容,或者如果不对该课进行重新分解,这是不可能进行测试的?

我尝试过所有不同的模拟类型(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;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:15)

MethodToMock不是虚拟的,因此无法模拟。您想要做的是使用部分模拟(我在类似于您的情况下完成它),但您想要模拟的方法必须是接口实现的一部分或标记为虚拟。否则,您无法使用Rhino.Mocks进行模拟。

答案 1 :(得分:1)

我建议在测试的类中使用 not 模拟方法,但是您的情况可能是唯一的,因为您无法重构该类以使其更容易在当前测试。您可以尝试显式创建委托以防止在设置调用时调用该方法。

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

或者,切换到使用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();
    }