• All Posts
  • Code
  • Design
  • Process
  • Speaking
  • Poetry
  • About
D.

July 28, 2011 Using Rhino.Mocks WhenCalled(...) - remember to Return(...)!

Today I was working with a repository that looked like this:

[csharp]public interface IRepository { … IQueryable<T> Get<T>(); IQueryable<T> Get<T>(Expression<Func<T, bool>> predicate); …. }[/csharp]

This allows consumers of the repo to shorten

[csharp gutter=”false”]var result = repo.Get<IWidget>().Where(w => w.Price > 10.00m);[/csharp]

to this:

[csharp gutter=”false”]var result = repo.Get<IWidget>(w => w.Price > 10.00m);[/csharp]

Not complicated but sure convenient when you are issuing a lot of queries against the repo.

In one test I had mocked the repo like so:

[csharp]List<IWidget> fakeWidgets;

IRepository mockRepo = MockRepository.GenerateMock<IRepostory>();

mockRepo.Expect(r => r.Get<IWidget>()).Return(fakeWidgets.AsQueryable());[/csharp]

What this does is create a fake IRepository instance and then set it up so that when any consumer calls Get<IWidget() it returns our collection of fakeWidgets.  The AsQueryable() call on the end is to transform our fake List<IWidget> into the IQueryable<IWidget> returned by Get<IWidget>().

That worked great for calls like

[csharp gutter=”false”]var result = repo.Get<IWidget>().Where(… some predicate …);[/csharp]

but failed, predictably, with a NullReferenceException on calls like

[csharp gutter=”false”]var result = repo.Get<IWidget>(… some predicate …);[/csharp]

So here’s how I first set up an expectation that would delegate this predicate:

[csharp]List<IWidget> fakeWidgets;

IRepository mockRepo = MockRepository.GenerateMock<IRepostory>();

mockRepo.Expect(r => r.Get<IWidget>()).Return(fakeWidgets.AsQueryable());

mockRepo.Expect(r => r.Get<IWidget>(Arg<Expression<Func<IWidget, bool>>>.Is.Anything)) .WhenCalled(invocation => { var predicate = invocation.Arguments.First() as Expression<Func<IWidget, bool>>; invocation.ReturnValue = mockRepo.Get<IWidget>().Where(predicate); });[/csharp]

Don't let the angle-brackets scare you; Arg<Expression<Func<IWidget, bool>>>.Is.Anything is simply Rhino Mocks’ way of saying accept any argument which looks like a function that takes an IWidget and returns a bool.

Then magic of the WhenCalled(…) method in line 8 is that it lets you manipulate a model of the actual method invocation which you are expecting. In this case on line 10 I’m grabbing that predicate argument matched in line 7 and then, on line 11, applying the predicate to the previously mocked Get<IWidget>() and stuffing it back into the method invocation as the actual ReturnValue.

What this effectively accomplishes is to make a call to the Get<IWidget>(predicate) method on that mocked IRepository act like a call to the Get<IWidget>() that has had the predicate applied.

Method … requires a return value or an exception to throw.

When I ran my test I got this error:

Method ‘IRepository.Get<IWidget>(anything);’ requires a return value or an exception to throw.

It took me a while to make sense of this message.

I had set the ReturnValue of the MethodInvocation passed to WhenCalled(...) so I figured Rhino Mocks knew the return value and I could safely drop the explicit Return(…) call that ends line 5

So what was going on?

Return(…) is required

Turns out Google and this post by Carlos Mendible came to my rescue.

The important part is that Rhino Mocks requires a Return(...) call at the end of an Expect(...) chain in order to determine the type of the return result.

Hence my delegating WhenCalled(...) code had to look like this:

[csharp highlight=”8”]mockRepo.Expect(r => r.Get<IWidget>(Arg<Expression<Func<IWidget, bool>>>.Is.Anything)) .WhenCalled(invocation => { var predicate = invocation.Arguments.First() as Expression<Func<IWidget, bool>>; invocation.ReturnValue = mockRepo.Get<IWidget>().Where(predicate); }) .Return(Enumerable.Empty<IWidget>().AsQueryable());[/csharp]

Now my calling client that used the shorter syntax behaves exactly as expected.


back to top

© David Alpert 2025