Want to show your appreciation?
Please a cup of tea.
Showing posts with label Mock. Show all posts
Showing posts with label Mock. Show all posts

Thursday, July 09, 2009

Some Utilities Extend Rhino.Mocks

I have recently blogged a few posts about how to let Rhino Mocks do more for us. They are listed below:

All those features require reader either change the source code of Rhino Mocks or download a special version of Rhino Mocks that I built. Those changes are quite invasive.

By carefully looking at the code, I found that there are some features can be extract into an extension library without touching the Rhino Mocks itself. Actually, only the ordered expectation requires source code change. Hence, I decided to build a extension library so that everybody can use. You can either drop the source into your test project or download the Rhino.Mocks.Extension.dll and add the reference to it.

Here is the current feature list:

  1. Create multi mock for AAA: Mockery.GenerateMultiMock
  2. Create partial mock for AAA: Mockery.GeneratePartialMock, Mocker.GeneratePartialMultiMock
  3. Ability to use test framework's assert: Assert.IsTrue(mock.ActivityOf(x=>x.Foo()));
  4. Use operator to check "or" condition: mock.ActivityOf(x=>x.Foo()) | mock2.ActivityOf(x=>x.Bar())
  5. Support assert for one and exactly one is called: Mockery.ExactOneOf(m.ActivityOf(...), ...).AssertOccured;

Please see my earlier posts for the detail of feature 3-5.

Wednesday, July 08, 2009

Introduce A Powerful AAA Syntax for Rhino.Mocks

I was again (last one was about ordered expectations for AAA) inspired by a question posted on the Rhino Mocks support email group, expect a call to any one of overloaded method. How do we do that? I have proposed a solution and that was pretty much what I did before. When we talk about TDD, we write the test before implementation. And sometimes, designer writes the test cases for somebody else to complete the implementation.

In many cases, all we care is that one of the send methods of the notification service is called. Which exact send method to call is all up to the implementation.

The Syntax

There got to be a better why to do this! The same may not necessary only apply to overloaded methods. For any methods, I should be able to just write something like this:

    ma.AssertWasCalled(a=>a.Foo()) or mb.AssertWasCalled(b=>b.Bar());

The experience gained from my work on the ordered expectation tells me that this is very possible. All I need to figure out is the syntax for this. May be

    ma.AssertWasCalled(a=>a.Foo()).Or(mb.AssertWasCalled(b=>b.Bar()));

or even better to use operator overload:

    ma.AssertWasCalled(a=>a.Foo()) | mb.AssertWasCalled(b=>b.Bar());

Well, the problem is that AssertWasCalled fails right away when a.Foo() is not called. Why do we have to fail it? Why cannot we leave it to the test framework to do the assert? But anyway, in order to not break the existing contract of AssertWasCalled, we'll have to use something different. How about this?

    Assert.IsTrue(ma.ActivityOf(a=>a.Foo()) || mb.ActivityOf(b=>b.Bar()));

Have more methods, not problem!

    Assert.IsTrue(foo.ActivityOf(a=>a.Foo(Arg<Something>.Is.Anything)) || 
        foo.ActivityOf(a=>a.Foo(Arg<Something>.Is.Anything, Arg<Another>.Is.NotNull)) || 
        foo.ActivityOf(a=>a.Foo(Arg<Something>.Is.Anything, Arg<Another>.Is.NotNull, Arg<int>Is.Anything)));

This syntax give us a lot of flexibility. I can use operator overload for ordered expectation as well.

    Assert.IsTrue(ma.ActivityOf(a=>a.Foo()) < mb.ActivityOf(b=>b.Bar()));

And there are unlimited possibilities, some examples below:

    // chained ordering
(m.ActivityOf(...) > m.ActivityOf(...) > m.ActivityOf(...)).AssertOccured;
    // mixed or ordering
(m.ActivityOf(...) | m.ActivityOf(...)) < m.ActivityOf(...)).AssertOccured
    var sent = (m.ActivityOf(a=>a.Sent(x)) | m.ActivityOf(a=>a.Sent(x, y)));
    Assert.IsTrue(sent); // assert sent is called
    Assert.IsTrue(sent < m.ActivityOf(a=>a.Close())); // assert sent called before close

Implementation

This is exciting, isn't it? How difficult to implement this? I give it a try by building on top of the changes that I made for the ordered expectation in the previous post. It turn out to be quite easy. Although the code below is no where close to perfect, and indeed it is quick and dirty to some extend, but it served well as proof of concept to introduce this technique.

Here we go the code. The Activities class is the core. It provides implementation for all the operator overload.

    public class Activities : IComparable<Activities>
    {
        private static readonly CallRecord[] _emptyRecords = new CallRecord[0];
        private readonly IList<CallRecord> _callRecords = _emptyRecords;
        private readonly ExpectationViolationException _exception;

        public Activities(IList<CallRecord> callRecords)
        {
            if (callRecords == null || callRecords.Count == 0)
                throw new ArgumentException(
                    "Must not be null or empty.", "callRecords");
            _callRecords = callRecords;
        }

        public Activities(ExpectationViolationException exception)
        {
            if(exception==null) throw new ArgumentNullException("exception");
            _exception = exception;
        }

        public bool Occured
        {
            get { return _callRecords.Count > 0; }
        }

        public Activities OccuredBefore(Activities other)
        {
            if (!Occured) return this;
            if (!other.Occured) return other;

            var thisLast = GetLast();
            CallRecord otherFirst = other._callRecords[0];

            return thisLast.Sequence < otherFirst.Sequence ? other
                : new Activities(NewOrderException(thisLast, otherFirst));
        }

        private ExpectationViolationException NewOrderException(
            CallRecord before, CallRecord after)
        {
            return new ExpectationViolationException(
                "Expected that call " + before.Method +
                " occurs before call " + after.Method +
                ", but the expectation is not satisfied.");
        }

        public Activities OccuredAfter(Activities other)
        {
            if (!Occured) return this;
            if (!other.Occured) return other;

            CallRecord otherLast = other.GetLast();
            CallRecord thisFirst = _callRecords[0];
            return otherLast.Sequence < thisFirst.Sequence ? other
                : new Activities(NewOrderException(otherLast, thisFirst));
        }

        public Activities Or(Activities other)
        {
            if (Occured) return this;
            if (other.Occured) return other;
            return new Activities(new ExpectationViolationException(
                this._exception.Message + "\nor\n" + other._exception.Message));
        }

        public Activities First {
            get {
                return Occured ? new Activities(new CallRecord[] {_callRecords[0]}) : this;
            }
        }

        public Activities Last {
            get {
                return Occured ? new Activities(new CallRecord[] { GetLast() }) : this;
            }
        }

        private CallRecord GetLast()
        {
            return _callRecords[_callRecords.Count - 1];
        }

        public int CompareTo(Activities other)
        {
            if (ReferenceEquals(this, other)) return 0;
            return OccuredBefore(other) ? -1 : 1;
        }

        public static implicit operator bool(Activities activities)
        {
            return activities.Occured;
        }

        public static Activities operator <(Activities a1, Activities a2)
        {
            return a1.OccuredBefore(a2);
        }

        public static Activities operator >(Activities a1, Activities a2)
        {
            return a1.OccuredAfter(a2);
        }

        public static Activities operator |(Activities a1, Activities a2)
        {
            return a1.Or(a2);
        }

        public static Activities operator ^(Activities a1, Activities a2)
        {
            return OneOf(a1, a2);
        }

        public static bool operator true(Activities a)
        {
            return a.Occured;
        }

        public static bool operator false(Activities a)
        {
            return !a.Occured;
        }

        public void AssertOccured()
        {
            if (_exception != null) throw _exception;
        }

        internal static Activities ExactOneOf(params Activities[] activitiesList)
        {
            Activities one = null;

            foreach (var activities in activitiesList)
            {
                if (!activities.Occured) continue;
                if (one == null) one = activities;
                else
                    return new Activities(
                        new ExpectationViolationException(
                            "Both " + one._callRecords[0].Method +
                            " and " + activities._callRecords[0].Method +
                            " was called"));
            }
            if (one != null) return one;

            StringBuilder sb = new StringBuilder("None of below is satisfied:");
            foreach (var activities in activitiesList)
            {
                sb.Append('\n').Append(activities._exception.Message);
            }
            return new Activities(new ExpectationViolationException(sb.ToString()));
        }
    }

The other class holds a few extension methods that glues this new API to existing Rhino Mocks.

    public static class Mockery
    {
        public static Activities ActivityOf<T>(this T mock, Action<T> action, 
            Action<IMethodOptions<object>> setupConstraints)
        {
            try
            {
                return new Activities(mock.AssertWasCalled(action, setupConstraints));
            }
            catch (ExpectationViolationException e)
            {
                return new Activities(e);
            }
        }

        public static Activities ActivityOf<T>(this T mock, Action<T> action)
        {
            return ActivityOf(mock, action, DefaultConstraintSetup);
        }

        public static Activities ActivityOf<T>(this T mock, Function<T, object> func, 
            Action<IMethodOptions<object>> setupConstraints)
        {
            return ActivityOf(mock, new Action<T>(t => func(t)), setupConstraints);
        }

        public static Activities ActivityOf<T>(this T mock, Function<T, object> func)
        {
            return ActivityOf(mock, func, DefaultConstraintSetup);
        }

        public static void Assert(Activities activities)
        {
            activities.AssertOccured();
        }

        public static Activities ExactOneOf(params Activities[] activitiesList)
        {
            return Activities.ExactOneOf(activitiesList);
        }

        private static void DefaultConstraintSetup(IMethodOptions<object> options)
        {
        }
    }

You can see that the implementation of the first ActivityOf method is very quick and dirty. The idea was to keep this POC code simple enough to illustrate the technique.

The Failure Message

There is one minor issue with using test framework's Assert.IsTrue. When the assert fails, it simply tells you that you expected true but got false. I don't see this as a big issue because with today's tool you can easily click on the error to jump to the exact line of code. In most of time, the code gives much more information then the message itself. But hey, it is always good to have detailed message right?

Careful reader must already found the Assert method in the Mockery class, that is the one used to replace the Assert.IsTrue. It provides "better" message then true/false. The reason for the quotation marks around the word better is that at this moment, the implementation can sometime provide ambiguous message. Again this is just a POC, in order to provide accurate message, we will need to make deeper changes into the Rhino Mocks.

Below are some examples from the unit test:

            Mockery.Assert(mb.ActivityOf(b => b.Bar()).First
                .OccuredBefore(ma.ActivityOf(a => a.Act()).First)
                .OccuredBefore(mb.ActivityOf(b => b.Bar()).Last));

            (mb.ActivityOf(b => b.Bar()).First
                < ma.ActivityOf(a => a.Act()).First
                < mb.ActivityOf(b => b.Bar()).Last).AssertOccured();
            Mockery.Assert(foo.ActivityOf(f => f.Foo(1)) | 
                foo.ActivityOf(f => f.Foo(Arg<int>.Is.Equal(1), Arg<int>.Is.Anything)));

            (foo.ActivityOf(f => f.Foo(Arg<int>.Is.Equal(1), Arg<int>.Is.Anything)) | 
                foo.ActivityOf(f => f.Foo(1))).AssertOccured();

C# 2.0 / VS2005 Support

It was said that the AAA for C# 2.0 is ugly and tedious. I tried to using this new API with C# 2.0 syntax. The result is not too bad at all. Let's take a look at what we have in the unit test cases:

            Mockery.Assert(Mockery.ActivityOf(ma, delegate(IA a) { a.Act(); }).Last
                .OccuredAfter(Mockery.ActivityOf(mb , delegate(IB b) { b.Bar(); }).Last)
                .OccuredAfter(Mockery.ActivityOf(ma, delegate(IA a) { a.Act(); }).First));

            (Mockery.ActivityOf(ma, delegate(IA a) { a.Act(); }).Last
                > Mockery.ActivityOf(mb, delegate(IB b) { b.Bar(); }).Last
                > Mockery.ActivityOf(ma, delegate(IA a) { a.Act(); }).First).AssertOccured();

            Mockery.Assert(
Mockery.ActivityOf(foo, delegate(IFoo f) { f.Foo(1); }) | Mockery.ActivityOf(foo, delegate(IFoo f) { f.Foo(Arg<int>.Is.Equal(1), Arg<int>.Is.Anything); }));

Give It A Try

If you want to give it a try, I have build a version of Rhino Mocks based on last trunk source with the latest Castle DynamicProxy2 at this moment. You can find them here:

http://code.google.com/p/kennethxublogsource/downloads/list

There are also other features in the build like:

  • Create multi mock for AAA: Mockery.GenerateMultiMock
  • Create partial mock for AAA: Mockery.GeneratePartialMock and Mocker.GeneratePartialMultiMock

Update (7/9/2009): For people don't want a modified version of Rhino.Mocks, I have made an extension library without the feature of ordered expectation: Some Utilities Extend Rhino.Mocks

Saturday, June 27, 2009

Rhino.Mocks Ordered Expectations for AAA Syntax

There was a question posted to the Google Group about how to make ordered expectations using AAA syntax in Rhino.Mocks. As people being increasingly aware of over specification using the record/reply model. Arrange-Action-Assert model is getting adopted by more and more developers. In the question, Alex was asking if is a way to make the ordered expectations using AAA syntax instead of the workaround he used below which is, IMHO, quite tedious to write and understand.

        public void ViewTitleSetBeforeShownInWorkspace()
        {
            //arrange
            var mockView = MockRepository.GenerateMock<IView>();
            bool viewTitleSet = false;
            mockView.Stub(x => x.Title = Arg<string>.Is.Anything)
                .WhenCalled(a => { viewTitleSet = true; });
            mockView.Stub(x => x.ShowInWorkspace("MyWorkspace"))
                .WhenCalled(a => { Assert.IsTrue(viewTitleSet, 
                    "View title should have been set first"); });

            //act
            var target = new Presenter(mockView);
            target.Initialize();

            //assert
            mockView.AssertWasCalled(x => x.ShowInWorkspace("MyWorkspace"));
        }

I agree with Ayende Rahien that ordered expectation is rare. But it does happen and I wish there is a way to do it when I need it. I again agreed that duplicating full ordering support from record/reply into AAA is too complex than worth. It would be not only over killed but also easily abused.

But, maybe there is a simpler way to the goal. All I need is to ensure one method should have been called before another, I want a way to verify this as easy as AssertWasCalled.

How about something like below:

            mockBefore.AssertWasCalled(b => b.MethodBefore())
                .Before(mockAfter.AssertWasCalled(a => a.MethodAfter()));

I loves to use open source tools because if nobody doing it then I do it myself. I checked out the Rhino.Mocks source code from Subversion repository. It turned out to be quite straightforward to make it work. Thanks to Ayende for the nice design. Going around the code and making changes were very easy. I was a bit afraid of scratching the crystal when making those changes. Ayende, please forgive me if I did.

Rhino.Mocks does record each call so that it can later use the information to verify the expectations. But the current design only records call parameters. I changed it to record a newly introduced CallRecord object.

    public class CallRecord
    {
        private static long sequencer = long.MinValue;

        internal CallRecord()
        {
            Sequence = Interlocked.Increment(ref sequencer);
        }
        internal object[] Arguments { get; set; }
        internal long Sequence { get; private set; }
        internal MethodInfo Method { get; set; }
    }

The key in this object is the sequencer. Every time a new CallRecord is created, the sequencer was increased in a thread safe manner. And the current sequence is recorded with the call. So each CallRecord object in the system has a unique Sequence value that can be used to determine the time order of the calls at later time.

The Arguments property is used by the original Rhino.Mocks to check expectations. Having Method property here was due to my laziness. There should be a better way to handle this for a lighter weight of CallRecord.

Next is to make the AssertWasCalled methods to return the CallRecord. Since the AssertWasCalled can match multiple method invocations. I made them return an IList<CallRecord>.

With the CallRecord information on hand, an extension method below can easily compare the order of the calls:

        public static void Before(this IList<CallRecord> beforeCalls, IList<CallRecord> afterCalls)
        {
            long maxBefore = long.MinValue;
            CallRecord latestBeforeCall = null;
            foreach (var call in beforeCalls)
            {
                var sequence = call.Sequence;
                if (sequence > maxBefore)
                {
                    maxBefore = sequence;
                    latestBeforeCall = call;
                }
            }

            long minAfter = long.MaxValue;
            CallRecord earliestAfterCall = null;
            foreach (var call in afterCalls)
            {
                var sequence = call.Sequence;
                if (sequence < minAfter)
                {
                    minAfter = sequence;
                    earliestAfterCall = call;
                }
            }
            if (maxBefore>minAfter)
            {
                throw new ExpectationViolationException(
                    "Expected that calls to " + latestBeforeCall.Method + 
                    " occurs before " + earliestAfterCall.Method + 
                    ", but the expectation is not satisfied.");

            }
        }

Again, I was lazy, the exception message should have been better formed, for example including the more detailed method signature and the real parameters. (Update: the API has been enhanced)

With all those in place, the final bit is to create a test cases to verify it works.

    [TestFixture] public class BeforeExtensionMethodTest
    {
        public interface IBefore  { void MethodBefore(); }

        public interface IAfter { void MethodAfter(); }

        [Test] public void Before_succeeds_if_beforeCalls_occured_before_afterCalls()
        {
            var mockBefore = MockRepository.GenerateStub<IBefore>();
            var mockAfter = MockRepository.GenerateStub<IAfter>();
            mockBefore.MethodBefore();
            mockBefore.MethodBefore();
            mockAfter.MethodAfter();
            mockAfter.MethodAfter();
            mockAfter.MethodAfter();
            mockBefore.AssertWasCalled(b => b.MethodBefore())
                .Before(mockAfter.AssertWasCalled(a => a.MethodAfter()));
        }

        [ExpectedException(typeof(ExpectationViolationException))]
        [Test] public void Before_chokes_if_one_of_beforeCalls_occured_after_any_of_afterCalls()
        {
            var mockBefore = MockRepository.GenerateStub<IBefore>();
            var mockAfter = MockRepository.GenerateStub<IAfter>();
            mockBefore.MethodBefore();
            mockAfter.MethodAfter();
            mockBefore.MethodBefore();
            mockAfter.MethodAfter();
            mockAfter.MethodAfter();
            mockBefore.AssertWasCalled(b => b.MethodBefore())
                .Before(mockAfter.AssertWasCalled(a => a.MethodAfter()));
        }
    }

The full patch for r2212 of https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/mocks/ can be downloaded here. Alex's original problem in the beginning now can be rewritten neatly.

        public void ViewTitleSetBeforeShownInWorkspace()
        {
            //arrange
            var mockView = MockRepository.GenerateMock<IView>();

            //act
            var target = new Presenter(mockView);
            target.Initialize();

            //assert
            mockView.AssertWasCalled(x => { x.Title = Arg<string>.Is.Anything; })
                .Before(mockView.AssertWasCalled(x => x.ShowInWorkspace("MyWorkspace")));
        }

Update 7/18: I made my customized version of Rhino Mocks available if you want to give it a try. It contains other enhancements.

Sunday, May 03, 2009

TypeMock - Are We Missing the Basic Point of Unit Test?

I started to use JMock since five years ago. Later NMock after I started coding in C# and then RhinoMocks. Today I gave TypeMock a look.

Certainly, I love the power that TypeMock brings. I can now Mock static and non-virtual methods that RhinoMocks cannot. This only happens when I'm force to use an invasive, class driven instead of interface driven application framework or 3rd party library that, IMHO, are anti-patterns.

Update (7/1/2009): Given another thought, do I really love the power that can be so easily abused and was massively encourage to do so? I don't think so! Below is a response to a questions about this article on Stack Overflow:

TypeMock website marketing aside, if you are dealing with sealed classes, etc. that you don't control and can't avoid, then it is great to have a tool such as TypeMock. – Troy DeMonbreun

There are many different ways to deal with sealed classes. One way is adapter pattern. Also MVP pattern helps to deal with poorly designed View framework. When my view is passive enough, I can afford not to test it. In almost all the cases when somebody come to me with a need of mocking a sealed class, it was solved by a better design, resulting in cleaner code that is easier to understand, maintain and test. To me, using TypeMock=="Open the door to design flaw" – Kenneth Xu

That is said, there are few important things that I cannot agree with TypeMock's marketing talk. I'm going to write two points today.

Inversion of Control (IoC), also known as Dependency Injection (DI) simplifies software development

I believe to some extend, TypeMock over promoted it's feature and misled developers by giving them false impression to the dependency injection framework. See quoted below.

http://www.typemock.com/Docs/writing_unit_tests_with_isolator.php: special and complex pattern called Inversion of Control ... ... require more development and complicated code that add complexity to development and maintenance

In this software development era, Inversion of Control is as populate, well adopted as Test Driven Design and Development. It is proven to promote better software design, enabling parallel development, simpler code, easier development and maintenance. Today, IoC is no longer special nor complex with the help of established frameworks like Spring.Net Application Framework and Castle Project. Please read on and I'll show you an example.

Unit test with detailed interaction is nothing but fool yourself.

Interaction test isn't necessary bad and sometime it is important. But the database access unit test example on TypeMock completely rewrote the original implementation almost literally one by one to replay the interaction in great detail is a disaster.

Any little change to the implementation can cause the test case to break. So you are force to change the test case for almost anything you did to the implementation code. While this clearly doubles your development work, do you get anything from this?

Did you notice in the video, how many times the presenter had to go back to the original code in order to complete his test case? By taking this approach, will you be able to write the test case first then write your implementation to pass the test case? The answer is simply no. This flat out against Test Driven Design and Development methodology.

Daniel has a very nice post for this. Although I don't necessary agree that all interaction test are bad but I certainly agree that interaction test is widely abused in unit testing. And unfortunately, TypeMock as one of major mock framework, advocating the abuse just to promote their unique feature, is selfish and short sighted.

The same database access code with IoC container

The database access unit test example on TypeMock site contains nothing but anti-patterns

  1. Data access method are static which is extremely hard to be replaced.
  2. I really don't know what to say when a data access method takes a connection string.
  3. reader and command objects are not dispose on exception.
  4. GetUserS actually return one user, always the first user in user table, are you kidding me?

Let's compare it with an implementation user IoC container Spring.Net which provide you with both GetUser and GetUsers. GetUser returns a user object for a given userId and GetUsers returns all users in the database. I believe you can tell which one is more simpler to code and easier to maintain.

    public class AdoDal: IDal
    {
        public virtual IAdoOperations AdoOperations { private get; set; }

        public virtual IList<User> GetUsers()
        {
            return AdoOperations.QueryWithRowMapperDelegate<User>(CommandType.Text,
                "SELECT UserId, UserName FROM dbo.Users", MapUser);
        }

        public virtual User GetUser(string userId)
        {
            return AdoOperations.QueryForObjectDelegate<User>(CommandType.Text,
                "SELECT UserId, UserName FROM dbo.Users WHERE UserId = @userId", MapUser, 
                "userId", DbType.String, 0, userId);
        }

        internal protected virtual User MapUser(IDataReader reader, int rowNum)
        {
            return new User {
                UserId = reader.GetString("UserId"),
                UserName = reader.GetString("UserName")
            };
        }
    }

Same lines of code, but

  1. We implemented two full functional methods instead of just a cripple one.
  2. Spring.Net ensures that reader, command and connection objects are properly disposed and closed.
  3. Works with any database, not just SqlClient.
  4. Each method can be easily tested.
    • Unit test needs no database, any fake, mock or stub would work. Not necessary TypeMock.
    • True integration test is possible and simple with in memory database.

Thursday, April 16, 2009

Rhino Mocks Strikes to Mock Non-Virtual Interface Implementation

Rhino Mocks has been my favorite mocking framework for a long time now and I'm more than a happy user. Today I got into a test scenario that seems to be straightforward but no matter how I struggle with it, Rhino Mocks refused to do its work.

That is a none virtual method on a class that I need to mock. Ok Ok, I hear you! Rhino Mocks cannot override none virtual method and declaring new is meaningless as you can never reference directly to the mock class. But the class implements an interface, "Then mock the interface!" I hear you again. Well, a) I don't want to mock every method or I would like to CallOriginalMethod; b) The class I want to mock is the class I want to test...

Totally confused? Let's jump to the code that will explain it better.

Let's say there is an interface and an implementation that I don't own

    public interface IDoNotOwn {
        int DirtyWork(int x);
        int Outer(int y);
    }

    public class DoNotOwn : IDoNotOwn {
        public int DirtyWork(int x) {
            // do something that hard for unit test to setup.
            throw new Exception("Don't call me in unit test");
        }

        public int Outer(int y) {
            return DirtyWork(y + y);
        }
    }

Unfortunately, it is out of my control that DoNotOwn implementation didn't declare the method to be virtual ("Many thanks" to Microsoft for the thoughtful default!)

I need to write my own implementation of IDoNotOwn but don't want to re-write the complex logic in the DirtyWork which is working perfectly fine. So naturally I have MyClass inherit from DoNotOwn.

    public class MyClass : DoNotOwn, IDoNotOwn {
        public new int Outer(int y) {
            return ((IDoNotOwn)this).DirtyWork(y*y);
        }
    }

So far everything looked normal and should just work fine. Let's write unit test for MyClass. I want to mock the call to the DirtyWork. Since my class implement an interface, I hope Rhino Mocks will be able to do that for me. My first attempt was easy to understand but didn't work.

    [TestFixture] public class MyClassTest {
        [Test] public void UsingRhinoMocks() {
            const int workResult = 293848;
            MockRepository mockery = new MockRepository();
            IDoNotOwn o = mockery.CreateMock<MyClass>();
            Expect.Call(o.DirtyWork(4)).Return(workResult);
            mockery.ReplayAll();
            Assert.That(o.Outer(2), Is.EqualTo(workResult));
            mockery.VerifyAll();
        }
    }

It gave me the Exception

System.Exception: Don't call me in unit test 
at MockDemo.DoNotOwn.DirtyWork(Int32 x) in MockDemoTest.cs: line 14
at MockDemo.MyClassTest.OuterMethod() in MockDemoTest.cs: line 33

Alright, so Rhino Mocks doesn't generate the method stub even if there is an interface exists. How about let me telling it explicitly? Let's give it second try by using MultiMock:

            IDoNotOwn o = mockery.CreateMultiMock<MyClass>(typeof(IDoNotOwn));

Now I got this:

Rhino.Mocks.Exceptions.ExpectationViolationException: IDoNotOwn.Outer(2); Expected #0, Actual #1. 
......
at MyClassProxybd7bb9a610da4d3fb0971368461c5b7c.Outer(Int32 y)
at MockDemo.MyClassTest.OuterMethod() in MockDemoTest.cs: line 35

Fine, I'll setup expectation and call the original method:

            IDoNotOwn o = mockery.CreateMultiMock<MyClass>(typeof(IDoNotOwn));
            Expect.Call(o.Outer(2)).CallOriginalMethod(OriginalCallOptions.NoExpectation);

Still, it throws me off

System.InvalidOperationException: Can't use CallOriginalMethod on method Outer because the method is abstract. 
at Rhino.Mocks.Impl.MethodOptions`1.AssertMethodImplementationExists()
at Rhino.Mocks.Impl.MethodOptions`1.CallOriginalMethod(OriginalCallOptions options)
at MockDemo.MyClassTest.OuterMethod() in MockDemoTest.cs: line 34

Now, I'm out of idea of using Rhino Mocks to achieve this. Anybody made this work with Rhino Mocks, please let me know.

I end up writing my own stub which worked very well for me. I believe the same kind of Stub can be easily generated by any mocking system.

        [Test] public void UsingMyStub() {
            const int workResult = 293848;
            MyClassStub stub = new MyClassStub();
            IDoNotOwn o = stub.ExpectCallDirtyWork(4).WillReturn(workResult);
            Assert.That(o.Outer(2), Is.EqualTo(workResult));
            stub.VerifyAll();
        }

        private class MyClassStub : MyClass, IDoNotOwn {
            private int _expectedI, _returnValue;
            private bool _isCalled;
            internal MyClassStub ExpectCallDirtyWork(int i) {
                _expectedI = i; return this;
            }

            internal MyClassStub WillReturn(int value) {
                _returnValue = value; return this;
            }

            internal void VerifyAll() {
                Assert.IsTrue(_isCalled, "Call to DirtyWork was not made.");
            }

            public new int DirtyWork(int i) {
                Assert.That(i, Is.EqualTo(_expectedI));
                Assert.IsFalse(_isCalled, "Duplicated call to DirtyWork.");
                _isCalled = true;
                return _returnValue;
            }
        }

Well, the example here is rather fictional but this all came out from a real world problme when writing the test cases for my OracleOdpTemplate.

Update

(4/19/2009) I asked in the RhinoMocks group mailing list. Tim Barcz reminded me about the adapter pattern. I didn't give that a consideration because, in my real world problem, I would have to wrote a hundred of methods plus their test cases if I attempt to adapt it. But after gave it another thought, I found that I can use a variation of adapter to help testing. Here is the changed the class.

        public class MyClass : DoNotOwn, IDoNotOwn {
            internal IDoNotOwn self;

            public MyClass() {
                self = this;
            }

            public new int Outer(int y) {
                return self.DirtyWork(y * y);
            }
        }

And the test case for it.

        [Test] public void UsingRhinoMocks() {
            const int workResult = 293848;
            MockRepository mockery = new MockRepository();
            var o = new MyClass {self = mockery.CreateMock<IDoNotOwn>()};
            Expect.Call(o.self.DirtyWork(4)).Return(workResult);
            mockery.ReplayAll();
            Assert.That(o.Outer(2), Is.EqualTo(workResult));
            mockery.VerifyAll();
        }

That worked fine for now but I still wish I can easily mock any interface method using RhinoMocks regardless of the virtual declaration of the implementation.