Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

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;
            }
        }
    }
}
like image 486
dotnet crazy kid Avatar asked May 04 '10 11:05

dotnet crazy kid


2 Answers

MethodToMock is not virtual and therefore can't be mocked. 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.

like image 117
PatrickSteele Avatar answered Sep 22 '22 03:09

PatrickSteele


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.

    [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();
    }
like image 29
tvanfosson Avatar answered Sep 22 '22 03:09

tvanfosson