Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,602
|
Comments: 51,232
Privacy Policy · Terms
filter by tags archive
time to read 1 min | 94 words

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.

time to read 3 min | 446 words

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.

time to read 2 min | 356 words

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.

time to read 1 min | 199 words

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!

time to read 2 min | 384 words

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.

time to read 1 min | 170 words

There has been an invaluable amount of discussion regarding the question I pose about the API design of Rhino Mocks 3.5. Jeremy Gray in particular has been helpful in making good suggestions and making the argument to simplify the API for developers who are not experts in TDD terminology and usage.

My current thinking is to combine GenerateMock() and GenerateStub() into a single method, GenerateTestDouble(). This method will return a dynamic mock.

If you want a true stub, you will be able to call myTestDouble.StubUnexpectedInteractions(). Note, since stubs have a special behavior for properties, I am also considering: myTestDouble.StubPropertiesAndUnexpectedInteractions(); .

If you want a strict mock, you will be able to call myTestDouble.FailOnUnexpectedInteractions();

Partial mock will not be supported by the static GenerateTestDouble method, and will require using the usual instance methods.

Calling VerifyAllExpectations() will be supported on all mocks.

The only remaining open question is whatever calling Expect() on an object that you previously called StubUnexpectedInteractions() should fail or not.

Thoughts?

time to read 2 min | 235 words

Let us say that we have the following code that we want to test:

public void ForgotMyPassword(string username)
{
   var user = users.GetUserByName(username);
   user.HashedPassword = "new pass";
   users.Save(user);
}

One way to write the test is:

public void When_user_forgot_password_should_save_user()
{
    var mockUserRepository = MockRepository.GenerateMock<IUserRepository>();
    var stubbedSmsSender = MockRepository.GenerateStub<ISmsSender>();

    var theUser = new User{HashedPassword = "this is not hashed password"};    

    mockUserRepository.Stub(x => x.GetUserByName("ayende")).Return(theUser);

    mockUserRepository.Expect( x => x.Save(theUser) );

    var controllerUnderTest = new LoginController(mockUserRepository, stubbedSmsSender);

    controllerUnderTest.ForgotMyPassword("ayende");

    mockUserRepository.VerifyAllExpectations();
}

Another would be:

public void When_user_forgot_password_should_reset_password()
{
    var stubUserRepository = MockRepository.GenerateStub<IUserRepository>();
    var stubbedSmsSender = MockRepository.GenerateStub<ISmsSender>();

    var theUser = new User{HashedPassword = "this is not hashed password"};    

    stubUserRepository.Stub(x => x.GetUserByName("ayende")).Return(theUser);

    var controllerUnderTest = new LoginController(mockUserRepository, stubbedSmsSender);

    controllerUnderTest.ForgotMyPassword("ayende");

    stubUserRepository.AssertWasCalled( x => x.Save(user));
}

Again, we have the question of should we even allow asserts on stubs. But beyond that, consider this two tests, both are functionally the same. Thoughts?

time to read 1 min | 51 words

Here is an interesting problem. What should this piece of code do?

var stubSmsSender = MockRepository.GenerateStub<ISmsSender>();
// test code
stubSmsSender.VerifyAllExpectations();

Right now this is a no-op.

But since stubs are explicitly not mocks, they shouldn't be verified. Should I throw here? For something which is a test design decision?

time to read 3 min | 448 words

Well, after a much longer beta period, and getting some very valuable input, Rhino Mocks 3.5 is out in Release Candidate. I am putting this out as RC, but I am pretty sure that those bits would be the RTM version as well.

The only major task left is to start documenting the changes. The move to 3.5 has made a lot changes in approach that I recommend to use (note that the API is compatible with 3.4).

I would like to thank Jordan Terrell, David Tchepak, Stefan Steinegger, Jason Meckley, Scott Brady, Ernst Naezer, Roelof Blom and Aaron Jensen for helping me get this out the door.

The changes (from 3.4) are:

  • Assert Act Arrange syntax, of course.
  • Better handling of exception in raising events from mock objects
  • Fixing an issue with mock objects that expose methods with output parameter of type System.IntPtr.
  • Allowing to return to record mode without losing expectations.
  • Inline constraints:
  • [Test]
    public void WhenUserForgetPasswordWillSendNotification_WithConstraints()
    {
        var userRepository = MockRepository.GenerateStub<IUserRepository>();
        var notificationSender = MockRepository.GenerateStub<INotificationSender>();
    
        userRepository.Stub(x => x.GetUserById(5)).Return(new User { Id = 5, Name = "ayende" });
    
        new LoginController(userRepository, notificationSender).ForgotMyPassword(5);
    
        notificationSender.AssertWasCalled(x => x.Send(Arg.Text.StartsWith("Changed") ));
    }
  • CreateMock() is deprecated and marked with the [Obsolete] attribute. Use StrictMock() instead.
  • Fixed an issue with merging, would cause issues if you are also using Castle Dynamic Proxy.
  • Fixed various typos
  • Better error handling for AAA syntax abuse
  • Will give better errors if you call Verify on a mock that is in record mode.
  • BackToRecord extension method.
  • Can mock interfaces with modopt params.
    • If you don't know what this means, it means that you can now mock interfaces that C++/CLI generates under some conditions (mixing native types with CLR types). This is probably the longest standing bug in Rhino Mocks.
  • Fixed issue with mocking internal classes and interfaces.
  • Full XML documentation
  • New event raising syntax:
    eventHolder.Raise(stub => stub.Blah += null, this, EventArgs.Empty);
  • AAA syntax now works with Ordering
  • Better error message if trying to use SetupResult on stubbed mock properties.

There are a lot of goodies in this release.

I am starting to create the documentation for this release here. This is a wiki, any help would be appreciated.

You can get the new version, for both 3.5 and 2.0 from the download page.

FUTURE POSTS

  1. A deep dive into RavenDB's AI Agents - 4 days from now
  2. Building an AI Agent using RavenDB - 7 days from now

There are posts all the way to Sep 12, 2025

RECENT SERIES

  1. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  2. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
  3. Webinar (7):
    05 Jun 2025 - Think inside the database
  4. Recording (16):
    29 May 2025 - RavenDB's Upcoming Optimizations Deep Dive
  5. RavenDB News (2):
    02 May 2025 - May 2025
View all series

Syndication

Main feed ... ...
Comments feed   ... ...
}