Ayende @ Rahien

It's a girl

The state of Rhino Mocks

I was asked to comment on the current state of Rhino Mocks. The current codebase is located here: https://github.com/hibernating-rhinos/rhino-mocks

The last commit was 2 years ago. And I am no longer actively / passively monitoring the mailing list.

From my perspective, Rhino Mocks is done. Done in the sense that I don’t have any interest in extending it, done in the sense that I don’t really use mocking any longer.

If there is anyone in the community that wants to steps in and take charge as the Rhino Mocks project leader, I would love that. Failing that, the code it there, it works quite nicely, but that is all I am going to be doing with this for the time being and the foreseeable future.

Tags:

Published at

Originally posted at

Comments (13)

Public Service Announcement: Git master repositories for the Rhino Tools projects

There have been some changes, and it seems that it is hard to track them. Here are where you can find the master repositories for the rhino tools projects:

Rhino Mocks, Github & Continuous Integration Builds

Well, it is official now, Rhino Mocks have a new home, and it is on github.

We had a chance to try several common development scenarios with it, accepting patches & commits from other people, and so far I can tell you that I am very impressed with the Git style workflow.

However, I know that many people aren’t comfortable with Git yet, so I decided to setup things to make things easier for everyone.

You can now access the output of Rhino Mocks CI process here:

http://builds.hibernatingrhinos.com/builds/Rhino-Mocks

Avé! Duci novo, similis duci seneci!

A while ago I was contacted by a friend who asked me if I am offering a commercial version of Rhino Mocks.

That is not a mistake, he was working in a place where the use of Open Source Software was not allowed, and decided that the simplest way to use the tool was to go through the normal route, buy it.

I wholeheartedly support this decision. :-)

Considering how hard it is to make some organizations use Open Source projects, and how used those same organizations to buying software, it is probably the right decision. It make things much simpler, and you are actually supporting OSS along the way.

At any rate, if you find yourself in the same position, you can just go and buy Rhino Mocks.

The retail version and the OSS version are… well, look at the title, then figure it out.

Planning for Rhino Mocks 4.0

Well, now that Rhino Mocks 3.6 is out of the way, we need to think about what the next version will look like.

Initially, I thought to match Rhino Mocks 4.0 to the .NET 4.0 release and support mocking dynamic variables, but while this is still on the planning board, I think that it is much more important to stop and take a look at where Rhino Mocks is now and where we would like it to be.

I started Rhino Mocks about 5 years ago, and the codebase has stood well in the test of time. There aren’t any nasty places and we can keep releasing new features with no major issues.

However, 5 years ago the community perception of mocking was different than what it is now. Rhino Mocks hasn’t really changed significantly since it 1.1 days, for that matter, you can take a code base using Rhino Mocks for .Net 1.1 and move it to Rhino Mocks 3.6 with no issues.

But one of the most frequent complaints that I have heard is that Rhino Mocks API has became too complex over the years, there are too many options and knobs that you can turn. I know that my own style of interaction testing has changed as well.

The current plan for Rhino Mocks 4.0 is that we will break backward compatibility in a big way. That means that we are going to drastically simplify everything in the framework.

We are still discussing this in the mailing list, but currently it looks like we will go with the following route:

  • Kill the dynamic, strict, partial and stub terminology. No one cares. It is a fake.
  • Remove the record / playback API. The AAA method is much simpler.
  • Simplify mocking options, aiming at moving as much as possible from expectation style to assert style.
  • Keep as much of the current capabilities as we can. That means that if Rhino Mocks was able to support a scenario, it should still support it for the 4.0 version, hopefully in a simpler fashion.

The end result is putting Rhino Mocks on an API diet. I am looking for help in doing this, both in terms of suggested syntax and in terms of actual patches.

You are welcome to contribute…

Rhino Mocks 3.6

This release is mostly to put out all the patches & fixes that went into Rhino Mocks since the 3.5 release, almost a year ago.

The changes from the previous version are:

  • Dynamic mocks and stubs will now assume that a call is match by any number of expectation.
  • Recursive mocks (with help from webpaul)
  • Fixing an issue with ArgManager in multi threaded scenarios (patch from Stefan Steinegger)
  • Fixing problem with IgnoreArguments() after Do() erasing the Do()
  • Fixing an issue with SetPropertyWithArgument improperly using LastCall.
  • Allowing Rhino Mocks to raise events on VB6 dlls.
  • Adding support for AssertWasCalled for getters (patch from robin clowers)
  • Adding remoting mocks as static methods (patch from Peter Mounce)
  • Adding a way to access the method from MethodInvocation
  • Fixing an issue with recursive return types when making a call to record an event more than once.
  • Various spelling & grammar issues (patch from Peter van der Woude)
  • Fixing an issue with stubbing MarshalByReferenceObjects
  • Better integration with Pex
  • Making LambdaConstraint work better with polymorphic args
  • Better feature parity for AAA with Record & Playback: Partials, Multis, and Stricts
  • Fixing an issue with stubbing properties of generic interfaces implemented twice using different generic parameters (Alexander Groß)

As usual, the download is here.

On PSake

James Kovacks introduced psake ( a power shell based build system )over a year ago, and at the time, I gave it a glance and decided that it was interesting, but not worth further investigation.

This weekend, as I was restructuring my Rhino Tools project, I realized that I need to touch the build system as well. The Rhino Tools build system has been through several projects, and was originally ported from Hibernate. It is NAnt based, complex, and can do just about everything that you want expect be easily understandable.

It became clear to me very quickly that it ain’t going to be easy to change the way it works, nor would it be easy to modify that to reflect the new structure. There are other issues with complex build systems, they tend to create zones of “there be dragons”, where only the initiated go, and even they go with trepidation. I decided to take advantage of the changes that I am already making to get a simpler build system.

I had a couple of options open to me: Rake and Bake.

Bake seemed natural, until I remember that no one touched it in a year or two. Beside, I can only stretch NIH so far :-). And while I know that people rave about rake, I did not want to introduce a Ruby dependency on my build system. I know that it was an annoyance when I had to build Fluent NHibernate.

One thing that I knew that I am not willing to go back to was editing XML, so I started looking at other build systems, ending up running into PSake.

There are a few interesting things that reading about it brought to mind. First, NAnt doesn’t cut it anymore. It can’t build WPF applications nor handle multi targeting well. Second, I am already managing the compilation part of the build using MSBuild, thanks to Visual Studio.

That leave the build system with executing msbuild, setting up directories, executing tests, running post build tools, etc.

PSake handles those well, since the execution environment is the command line. The syntax is nice, just enough to specify tasks and dependencies, but everything else is just pure command line. The following is Rhino Mocks build script, using PSake:

properties { 
  $base_dir  = resolve-path .
  $lib_dir = "$base_dir\SharedLibs"
  $build_dir = "$base_dir\build" 
  $buildartifacts_dir = "$build_dir\" 
  $sln_file = "$base_dir\Rhino.Mocks-vs2008.sln" 
  $version = "3.6.0.0"
  $tools_dir = "$base_dir\Tools"
  $release_dir = "$base_dir\Release"
} 

task default -depends Release

task Clean { 
  remove-item -force -recurse $buildartifacts_dir -ErrorAction SilentlyContinue 
  remove-item -force -recurse $release_dir -ErrorAction SilentlyContinue 
} 

task Init -depends Clean { 
    . .\psake_ext.ps1
    Generate-Assembly-Info `
        -file "$base_dir\Rhino.Mocks\Properties\AssemblyInfo.cs" `
        -title "Rhino Mocks $version" `
        -description "Mocking Framework for .NET" `
        -company "Hibernating Rhinos" `
        -product "Rhino Mocks $version" `
        -version $version `
        -copyright "Hibernating Rhinos & Ayende Rahien 2004 - 2009"
        
    Generate-Assembly-Info `
        -file "$base_dir\Rhino.Mocks.Tests\Properties\AssemblyInfo.cs" `
        -title "Rhino Mocks Tests $version" `
        -description "Mocking Framework for .NET" `
        -company "Hibernating Rhinos" `
        -product "Rhino Mocks Tests $version" `
        -version $version `
        -clsCompliant "false" `
        -copyright "Hibernating Rhinos & Ayende Rahien 2004 - 2009"
        
    Generate-Assembly-Info `
        -file "$base_dir\Rhino.Mocks.Tests.Model\Properties\AssemblyInfo.cs" `
        -title "Rhino Mocks Tests Model $version" `
        -description "Mocking Framework for .NET" `
        -company "Hibernating Rhinos" `
        -product "Rhino Mocks Tests Model $version" `
        -version $version `
        -clsCompliant "false" `
        -copyright "Hibernating Rhinos & Ayende Rahien 2004 - 2009"
        
    new-item $release_dir -itemType directory 
    new-item $buildartifacts_dir -itemType directory 
    cp $tools_dir\MbUnit\*.* $build_dir
} 

task Compile -depends Init { 
  exec msbuild "/p:OutDir=""$buildartifacts_dir "" $sln_file"
} 

task Test -depends Compile {
  $old = pwd
  cd $build_dir
  exec ".\MbUnit.Cons.exe" "$build_dir\Rhino.Mocks.Tests.dll"
  cd $old        
}

task Merge {
    $old = pwd
    cd $build_dir
    
    Remove-Item Rhino.Mocks.Partial.dll -ErrorAction SilentlyContinue 
    Rename-Item $build_dir\Rhino.Mocks.dll Rhino.Mocks.Partial.dll
    
    & $tools_dir\ILMerge.exe Rhino.Mocks.Partial.dll `
        Castle.DynamicProxy2.dll `
        Castle.Core.dll `
        /out:Rhino.Mocks.dll `
        /t:library `
        "/keyfile:$base_dir\ayende-open-source.snk" `
        "/internalize:$base_dir\ilmerge.exclude"
    if ($lastExitCode -ne 0) {
        throw "Error: Failed to merge assemblies!"
    }
    cd $old
}

task Release -depends Test, Merge {
    & $tools_dir\zip.exe -9 -A -j `
        $release_dir\Rhino.Mocks.zip `
        $build_dir\Rhino.Mocks.dll `
        $build_dir\Rhino.Mocks.xml `
        license.txt `
        acknowledgements.txt
    if ($lastExitCode -ne 0) {
        throw "Error: Failed to execute ZIP command"
    }
}

It is about 50 lines, all told, with a lot of spaces and is quite readable.

This handles the same tasks as the old set of scripts did, and it does this without undue complexity. I like it.

The complexity of unity

This post is about the Rhino Tools project. It has been running for a long time now, over 5 years, and amassed quite a few projects in it.

I really like the codebase in the projects in Rhino Tools, but secondary aspects has been creeping in that made managing the project harder. In particular, putting all the projects in a single repository made it easy, far too easy. Projects had an easy time taking dependencies that they shouldn’t, and the entire build process was… complex, to say the least.

I have been somewhat unhappily tolerant of this so far because while it was annoying, it didn’t actively create problems for me so far. The problems started creeping when I wanted to move Rhino Tools to use NHibernate 2.1. That is when I realized that this is going to be a very painful process, since I have to take on the entire Rhino Tools set of projects in one go, instead of dealing with each of them independently. the fact that so many of the dependencies where in Rhino Commons, to which I have a profound dislike, helped increase my frustration.

There are other things that I find annoying now, Rhino Security is a general purpose library for NHibernate, but it makes a lot of assumptions about how it is going to use, which is wrong. Rhino ETL had a dependency on Rhino Commons because of three classes.

To resolve that, I decided to make a few other changes, taking dependencies is supposed to be a hard process, it is supposed to make you think.

I have been working on splitting the Rhino Tools projects to all its sub projects, so each of them is independent of all the others. That increase the effort of managing all of them as a unit, but decrease the effort of managing them independently.

The current goals are to:

  • Make it simpler to treat each project independently
  • Make it easier to deal with the management of each project (dependencies, build scripts)

There is a side line in which I am also learning to use Git, and there is a high likelihood that the separate Rhino Tools projects will move to github. Suversion’s patching & tracking capabilities annoyed me for the very last time about a week ago.

Recursive Mocking

This now works :-)

image

The challenge is still open, I intentionally stopped before completing the feature, and there is a failing test in the RecusriveMocks fixture that you can start from.

And just to give you an idea about what I am talking about, please run this and examine the results:

svn diff https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk -r 1682:1683

A really cool web view of them is here.

Request for comments: Changing the way dynamic mocks behave in Rhino Mocks

I have just committed a change to the way Rhino Mocks handles expectations for dynamic mocks and stubs.  Previously, the meaning of this statement was "expect Foo() to be called once and return 1 when it does":

Expect.Call( bar.Foo ).Return(1);

Now, the meaning of this is: "expect Foo() to be called one or more times, and return 1 when it does". This means that this will work:

Assert.AreEqual(1, bar.Foo);
Assert.AreEqual(1, bar.Foo);
Assert.AreEqual(1, bar.Foo);

Where as previously, using dynamic mocks, it would fail on the second assert, because the expectation that was setup was consumed. I think that this is a more natural way to behave, but this is a subtle breaking change.
You can get the old behavior by specifying .Repeat.Once().

Thoughts?

Rhino Mocks 3.5 Gems - Explicit Property Setting Expectations

This post is derived from the Rhino Mocks 3.5 documentation.

Setting expectations for property set was always very simple, and slightly confusing with Rhino Mocks. Here is how you do it:

view.Username = "the user name";	

The problem is that it is hard to see that there is an expectation created here. So, with the generous help of Sebastian Jancke, we have a new syntax:

Expect.Call(view.Username).SetPropertyWithArguments("the user name");

This is much more explicit and easier to understand. We can also set expectation on the property set, without expecting a certain value using this syntax:

Expect.Call(view.Username).SetPropertyAndIgnoreArguments();

Rhino Mocks Challenge: Implement This Feature

Okay, let us see if this approach works...

Here is a description of a feature that I would like to have in Rhino Mocks (modeled after a new feature in Type Mock). I don't consider this a complicated feature, and I would like to get more involvement from the community in building Rhino Mocks (see the list of all the people that helped get Rhino Mocks 3.5 out the door).

The feature is fluent mocks. The idea is that this code should work:

var mockService = MockRespository.GenerateMock<IMyService>();
Expect.Call( mockService.Identity.Name ).Return("foo");

Assert.AreEqual("foo", mockService.Identity.Name);

Where identity is an interface.

The best place to capture such semantics is in the RecordMockState.

Have fun, and send me the patch :-)

Rhino Mocks 3.5 RTM

Today I decided that I had enough time to get bugs for the 3.5 RC, so I fixed all the remaining bugs, updated the Rhino Mocks 3.5 Documentation, and put the binaries out the site.

For this release, I actually have 4 binary packages. One for .NET 3.5 and one for .NET 2.0, but I have an additional criteria, with the castle assemblies merged (default) and with the castle assemblies included). The reason for having those two options is that people who want to extend Rhino Mocks directly can do it more easily. In general, I suggest using the merged version.

So, what do we actually have here (feature differences from 3.4)?

Features:

  • Assert Act Arrange syntax for mocking
    • Including support for .NET 2.0
  • Added a way to access the mocked method at runtime, using WhenCalled (similar to Do(), but without the pain of having to specify a special delegate).
  • CreateMock() is deprecated and marked with the [Obsolete] attribute. Use StrictMock() instead.
  • Support for mocking interface in C++ that mix native and managed types. (Note, may require that you install kb957541 to get around bug introduced to the framework on SP1).
  • New event raising syntax:
    eventHolder.Raise(stub => stub.Blah += null, this, EventArgs.Empty);
  • Better support for multi threaded replays.
    • Note that access to the mock object is now serialized.
  • Support AssertWasCalled on parial mocks.

Patches:

  • From Sebastian Jancke, adding support for SetPropertyAndIgnoreArguments() and SetPropertyWithArguments( o );
  • From Yann Trevin, adding support for List.Element("MyKey", ...), so we are not limited to just integers.
  • From David Tchepak, adding support for ctor arguments when creating a mock using static method.
  • From Stefan Steinegger - much better support for creating inline constraints.

Improvements:

  • Better handling of exception in raising events from mock objects
  • Better error message when trying to set expectation on properties of a stub.
  • Better error handling for AAA syntax abuse
  • Will give better errors if you call Verify on a mock that is in record mode.
  • Allowing to return to record mode without losing expectations.
  • BackToRecord extension method.
  • AAA syntax now works with Ordering
  • Better error message if trying to use SetupResult on stubbed mock properties.
  • Better error message when trying to mock null instance.

Bug fixes:

  • Fixing an issue with mock objects that expose methods with output parameter of type System.IntPtr.
  • Fixed an issue with merging, would cause issues if you are also using Castle Dynamic Proxy.
  • Fixed various typos
  • Fixed issue with mocking internal classes and interfaces.
  • OutRef params was not copied when creating new expectation from an existing one.
  • Fixing an issue with leaking expectationReplaced in mocks.

How .Net 3.5 SP1 broke Rhino Mocks

Okay, now that we are over the sensationalist headline, the actual problem is more complex than that. Let us assume that we have the following interface:

public interface IComplexGeneric<T>
{
void GenericMethod<K>();
}

Up until .Net 3.5 SP1, Rhino Mocks was perfectly happy to deal with such an interface (well, not happy, exactly, that requires some hard core code). With .Net 3.5 SP1, this generate an Execution Engine Exception.

Fabian Schmied was kind enough to prove that select is broken here. This is the connect site issue, and I would appreciate it if you can vote for it.

The work around for this would mean that I will have to remove support for mocking F#, C++ and Spec# from Rhino Mocks, and I am reluctant to do so.

This is fixed,  you can get the fix here: http://support.microsoft.com/?id=957541

Mocking the file system

I have the following piece of code:

image

And I wasn't sure about how I can test this thing. For production, this will use a File Stream, and getting those to produce errors is non trivial in most situations. A bit of thinking, however, told me that I can write a test for the error handling section of this fairly easily, like this:

 

image

I love having powerful tools at my reach.

Beautiful (nontrivial) Code - Rhino Mocks 3.5's AssertWasCalled

Beautiful code is not something that is easy to define. I think of this as something that is extremely elegant, that solve a hard problem in a way that isn't brute force. I think that the way Rhino Mocks implements the AssertWasCalled functionality is elegant, and I would like to point it out.

I know of at least one contributor to Rhino Mocks who consider that piece of code scary, by the way, so it is not cut & dry.

Here is the actual method call:

public static void AssertWasCalled<T>(this T mock, Action<T> action, 
	Action<IMethodOptions<object>> setupConstraints)
{
	ExpectationVerificationInformation verificationInformation = 
		GetExpectationsToVerify(mock, action, setupConstraints);

	foreach (var args in verificationInformation.ArgumentsForAllCalls)
	{
		if (verificationInformation.Expected.IsExpected(args))
		{
			verificationInformation.Expected.AddActualCall();
		}
	}
	if (verificationInformation.Expected.ExpectationSatisfied)
		return;
	throw new ExpectationViolationException(
		verificationInformation.Expected.BuildVerificationFailureMessage());
}

We will get the GetExpectaionsToVerify in a bit, but broadly, it gets the expectation that should have been called and then it execute the same logic that it would have in the Record/Replay model. In fact, it is an exact reversal of the Record/Replay model. Now we record all the actual calls, and then we create an expectation and try to match it against the actual calls that were made against the actual object.

Of even more interest is how we get the expectation that we are verifying:

private static ExpectationVerificationInformation GetExpectationsToVerify<T>(T mock, Action<T> action,
		Action<IMethodOptions<object>> setupConstraints)
{
	IMockedObject mockedObject = MockRepository.GetMockedObject(mock);
	MockRepository mocks = mockedObject.Repository;

	if (mocks.IsInReplayMode(mockedObject) == false)
	{
		throw new InvalidOperationException(
			"Cannot assert on an object that is not in replay mode." +
			" Did you forget to call ReplayAll() ?");
	}

	var mockToRecordExpectation = (T)mocks.DynamicMock(
		mockedObject.ImplementedTypes[0], 
		mockedObject.ConstructorArguments);

	action(mockToRecordExpectation);

	AssertExactlySingleExpectaton(mocks, mockToRecordExpectation);

	IMethodOptions<object> lastMethodCall = mocks.LastMethodCall<object>(mockToRecordExpectation);
	lastMethodCall.TentativeReturn();
	if (setupConstraints != null)
	{
		setupConstraints(lastMethodCall);
	}
	ExpectationsList expectationsToVerify = 
		mocks.Replayer.GetAllExpectationsForProxy(mockToRecordExpectation);
	if (expectationsToVerify.Count == 0)
	{
		throw new InvalidOperationException(
			"The expectation was removed from the waiting expectations list,"+
			" did you call Repeat.Any() ? This is not supported in AssertWasCalled()");
	}
	IExpectation expected = expectationsToVerify[0];
	ICollection<object[]> argumentsForAllCalls = mockedObject.GetCallArgumentsFor(expected.Method);
	return new ExpectationVerificationInformation
			{
				ArgumentsForAllCalls = new List<object[]>(argumentsForAllCalls),
				Expected = expected
			};
}

This is even more interesting. We create a new mocked object, and execute it in record mode against the expectation that we wish to verify. We gather this expectation and extract that from the newly created mock object, to pass it to the AssertWasCalled method, where we verify that against the actual calls made against the object.

What I find elegant in the whole thing is not just the reversal of the record / replay model, it is the use of Rhino Mocks to extend Rhino Mocks.

Where mocking fails

I mentioned before that Rhino Mocks is a very powerful framework. This can be a problem at times, because it make it hard to notice that you cross the line into mock abuse.

Let us look at this test for example:

[Test]
public void Will_raise_message_arrived_event_for_each_message_in_batch_and_across_batches()
{
	var stubbedIncomingMessageRepository = MockRepository.GenerateStub<IIncomingMessageRepository>();
	var queue = new Queue(new Uri("queue://localhost/testQueue"),
						  MockRepository.GenerateStub<IOutgoingMessageRepository>(),
						  stubbedIncomingMessageRepository);
	var msgQueue = new Queue<QueueMessage>();

	stubbedIncomingMessageRepository
		.Stub(x => x.GetEarliestMessage())
		.Return(null)
		.Do(invocation =>
		{
			lock (msgQueue)
			{
				invocation.ReturnValue = msgQueue.Count == 0 ? null : msgQueue.Dequeue();
			}
		})
		.Repeat.Any();
	stubbedIncomingMessageRepository
		.Stub(x => x.Transaction(Arg<Action>.Is.Anything))
		.Do(invocation => ((Action) invocation.Arguments[0])())
		.Repeat.Any(); ;
	stubbedIncomingMessageRepository
		.Stub(x => x.Save(Arg<QueueMessage>.Is.Anything))
		.Do(invocation =>
		{
			lock (msgQueue)
			{
				msgQueue.Enqueue((QueueMessage)invocation.Arguments[0]);
			}
		})
		.Repeat.Any();

	var callCount = 0;
	var e = new ManualResetEvent(false);
	queue.MessageArrived += (obj =>
	{
		if (Interlocked.Increment(ref callCount) >= 100)
			e.Set();
	});
	for (int i = 0; i < 50; i++)
	{
		queue.AcceptMessages(
			new QueueMessage(), 
			new QueueMessage()
			);
	}
	e.WaitOne();
	Assert.AreEqual(100, callCount);
}

Here we are using Rhino Mocks to fake the entire behavior of the type. Note the thread handling in the mock object, yuck! A large portion of the test is implementing a fake message queue, in a non intuitive way.

Let us explore a better way:

[Test]
public void Will_raise_message_arrived_event_for_each_message_in_batch_and_across_batches()
{
	var queue = new Queue(new Uri("queue://localhost/testQueue"),
						  MockRepository.GenerateStub<IOutgoingMessageRepository>(),
						  new FakeIncomingMessageRepository());

	var callCount = 0;
	var e = new ManualResetEvent(false);
	queue.MessageArrived += (obj =>
	{
		if (Interlocked.Increment(ref callCount) >= 100)
			e.Set();
	});
	for (int i = 0; i < 50; i++)
	{
		queue.AcceptMessages(
			new QueueMessage(), 
			new QueueMessage()
			);
	}
	e.WaitOne();
	Assert.AreEqual(100, callCount);
}

public class FakeIncomingMessageRepository : IIncomingMessageRepository
{
	readonly Queue<QueueMessage> msgQueue = new Queue<QueueMessage>();

	public QueueMessage GetEarliestMessage()
	{
		lock (msgQueue)
		{
			return msgQueue.Count == 0 ? null : msgQueue.Dequeue();
		}
	}

	public void Save(QueueMessage msg)
	{
		lock(msgQueue)
		{
			msgQueue.Enqueue(msg);
		}
	}

	public void Transaction(Action action)
	{
		action();
	}
}

Here we handed coded the fake object, and used that in the test. The reduction in complexity is quite significant.

So, when should you avoid mocks? When there is more pain in using them than not.

Not a helpful metric, but that is how I do it.

Advance Mocking with Rhino Mocks 3.5

Here is why I love Rhino Mocks. This is a test that utilize quite a bit of the underlying power of Rhino Mocks. Check this out:

[Test]
public void For_each_batch_from_repository_will_create_and_execute_command()
{
	var stubbedCommand = MockRepository.GenerateMock<ICommand>();
	var mocks = new MockRepository();
	var queueProcessor = mocks.PartialMock<QueueProcessor>(
		stubbedQueueFactory, 
		stubbedOutgoingMessageRepository);

	queueProcessor
		.Stub(x => x.CreateCommand(Arg<SingleDestinationMessageBatch>.Is.Anything))
		.Return(stubbedCommand)
		.Repeat.Any();

	stubbedCommand.Expect(x => x.Execute()).Repeat.Times(3);

	mocks.ReplayAll();

	stubbedOutgoingMessageRepository
		.Stub(x => x.GetBatchOfMessagesToSend())
		.Return(new MessageBatch
		{
			DestinationBatches = new[]
			{
				new SingleDestinationMessageBatch(),
				new SingleDestinationMessageBatch(),
				new SingleDestinationMessageBatch(),
			}
		});

	stubbedOutgoingMessageRepository
		.Stub(x => x.GetBatchOfMessagesToSend())
		.Return(new MessageBatch())
		.Do(delegate { queueProcessor.Stop(); });

	queueProcessor.Run();

	stubbedCommand.VerifyAllExpectations();
}

I use a partial mock to override a single method, use AAA for really nice syntax, the new Do() to allow me to have fine grain control over what is going on and in general mess about with complete control over all the knobs there are.

And just for completion sake, here is the code under test:

public void Run()
{
	while (shouldStop == false)
	{
		checkForMessages.WaitOne(TimeSpan.FromSeconds(1), false);
		MessageBatch messageBatch;
		do // as long as there are messages we don't want to wait
		{
			messageBatch = outgoingMessageRepository.GetBatchOfMessagesToSend();
			foreach (var batch in messageBatch.DestinationBatches)
			{
				ICommand cmd = CreateCommand(batch);
				cmd.Execute();
			}
		} while (messageBatch.IsEmpty == false && shouldStop == false);
	}
}

Sweet!

Rhino Mocks 3.5: A feature to be proud of - seamless Do()

image One of the major pain points for me in Rhino Mocks has always been the Callback() and Do() delegates. I designed them at the 1.1 days, when we didn't have such things as anonymous delegates or lambda. As a result, they required you to explicitly pass a delegate type, where a pain to use and major eye sore.

For a long time, I accepted that there is nothing to do. The fault was with the annoying compiler, and like many other language limitations, you just have to live with it.

I was writing something today and I really want to be able to use Do(), but I had zero intention of getting into that mess again. And suddenly it hit me.

I was doing it all wrong. I should be trying to get the user to do the work, instead of the compiler. Here is the deal, the original design of Do() include matching the called method signature. But most often, you don't care about that.

Once I realized that, I realized that my issue all along was the insistence that it should be strongly typed. There isn't any really reason why this should be so. And once you let go of that, you can get this really cool syntax:

[Test]
public void Can_use_when_called_to_exceute_code_when_exceptation_is_matched_ \
                 without_stupid_delegate_sig_overhead()
{
	var wasCalled = true;
	var stub = MockRepository.GenerateStub<IDemo>();
	stub.Stub(x => x.StringArgString(Arg.Is("")))
		.Return("blah")
		.Do(delegate { wasCalled = true; });
	Assert.AreEqual("blah", stub.StringArgString(""));
	Assert.IsTrue(wasCalled);
}

Oh, and it even allows you to directly modify the method return value:

[Test]
public void Can_modify_return_value()
{
	var wasCalled = true;
	var stub = MockRepository.GenerateStub<IDemo>();
	stub.Stub(x => x.StringArgString(Arg.Is("")))
		.Return("blah")
		.Do(invocation => invocation.ReturnValue = "arg");
	Assert.AreEqual("arg", stub.StringArgString(""));
	Assert.IsTrue(wasCalled);
}

You can also inspect the method arguments and make decisions based on that:

[Test]
public void Can_inspect_method_arguments()
{
	var wasCalled = true;
	var stub = MockRepository.GenerateStub<IDemo>();
	stub.Stub(x => x.StringArgString(null))
		.IgnoreArguments()
		.Return("blah")
		.Do(invocation => Assert.AreEqual("foo", invocation.Arguments[0]));
	Assert.AreEqual("blah", stub.StringArgString("foo"));
	Assert.IsTrue(wasCalled);
}

Overall, this just equaled to the entire AAA syntax in my level of pain reduction.