Rhino Mocks 2.3.5 and events

time to read 14 min | 2704 words

The release is available here.

Another bug fix release, this time allowing to mock interfaces that inherits from IClonaeble. But this isn't the reason for the post, I wanted to talk about using events in a mocking framework. As events are such an important part of the .Net framework, I decided (encouraged by a user question) to check to see how it works. I wasn't surpirsed (DynamicProxy is cool) to see it was already inside and very easy to do.

Here is how you check that the object under test subscribe to an event on a mock object:

public interface IWithEvents

{

     event EventHandler Blah;

     void RaiseEvent();

}

 

[Test]

public void VerifyingThatEventWasAttached()

{

     using(MockRepository mocks = new MockRepository())

     {

           IWithEvents events = (IWithEvents)mocks.CreateMock(typeof(IWithEvents));

           events.Blah+=new EventHandler(events_Blah);

           mocks.ReplayAll();

           MethodThatSubscribeToEventBlah(events);

     }

}

 

public void MethodThatSubscribeToEventBlah(IWithEvents events)

{

     events.Blah+=new EventHandler(events_Blah);

}

You just record that you want to subscribe to the event and then run the code that is supposed to subscribe to it.

Now, let's try do it from the other side, how do check that an event was raised? Well, that is a little more complicated, but not very much so. We need to do create an interface with a matching method name, create a mock from this interface, and then just subscribe to the event and record any expectations regarding the method. As usual, the code is clearer then the explanation:

public interface IEventSubscriber

{

     void Hanlder(object sender, EventArgs e);

}

 

public class WithEvents : IWithEvents

{

     #region IWithEvents Members

 

     public event System.EventHandler Blah;

 

     public void RaiseEvent()

     {

           if (Blah!=null)

                Blah(this, EventArgs.Empty);

     }

 

     #endregion

}

 

[Test]

public void VerifyingThatAnEventWasFired()

{

     using(MockRepository mocks = new MockRepository())

     {

           IEventSubscriber subscriber = (IEventSubscriber)mocks.CreateMock(typeof(IEventSubscriber));

           IWithEvents events = new WithEvents();

          // This doesn't create an expectation because no method is called on subscriber!!

           events.Blah+=new EventHandler(subscriber.Hanlder);

           subscriber.Hanlder(events, EventArgs.Empty);

           mocks.ReplayAll();

           events.RaiseEvent();

     }

}

One thing to notice here is that subscribing to the event does not create an expectation, since no action is taken on the subscriber instance. Then, to create an expectation that the method will be raised with the specified arguments, we just call the method we just subscribed. Since the raised event will eventually resolve itself to the same method call, everything works as expected.

Expect more Rhino Mocks goodies later today :-)