Getting Rhino Mocks and Events to play nicely together
I was having some problems getting one of my unit tests that used Rhino Mocks to run correctly.
The problem was setting up an expectation on a mock that exposed an event that my tested class subscribes to.
I kept getting two ExpectationViolationException one of them indicating that a unrecorded call was executed on the mock object and the other stated that an expected call wasn’t actually called. The following code reproduces the error:
public interface IEventSource
{
event EventHandler PublishedEvent;
}
public class EventSubscriber
{
public EventSubscriber(IEventSource evnrSrc)
{
evnrSrc.PublishedEvent += new EventHandler(m_EvntSrc_PublishedEvent);
}
private void m_EvntSrc_PublishedEvent(object sender, EventArgs e)
{
// Do what ever
}
}
[Test]
public void CheckEventSubscription()
{
MockRepository mocks = new MockRepository();
IEventSource mock = (IEventSource)mocks.CreateMock(typeof(IEventSource));
mock.PublishedEvent += new EventHandler(mock_PublishedEvent);
LastCall.On(mock);
mocks.ReplayAll();
EventSubscriber subscriber = new EventSubscriber(mock);
mocks.VerifyAll();
}
It turns out that due to the way Rhino Mocks records expectations
The following calls are not considered identical
The recorded expectation:
mock.PublishedEvent += new EventHandler(mock_PublishedEvent);
The actual call:
evnrSrc.PublishedEvent += new EventHandler(m_EvntSrc_PublishedEvent);
Rhino Mocks differentiates the two becouse the MethodInfo of the event handlers don’t match whice inturn produces a mismatch between the expectation and the actual call hence the two ExpectationViolationException exceptions received when running the test.
In order to fix this we need to modify our expectation recording in a way that tells Rhino Mocks to discard the parameters of the call when subscribing to the event.
This is done easly by modifying the folowing line of code:
LastCall.On(mock);
To this:
LastCall.On(mock).IgnoreArguments();
That’s it, we are done. The test passes with flying (green) colors.