Friday, February 29, 2008

Test Multiple Events with Rhino.Mocks

The situation when you should test the raising of one event with Rhino.Mocks is well documented/ But what to do if your page have 2 or more events?
Here is one of possible solutions:

using System;
using System.Collections.Generic;
using MyProject.Presenters;
using MyProject.Presenters.Interfaces;
using NUnit.Framework;
using Rhino.Mocks;
using Rhino.Mocks.Constraints;
using Rhino.Mocks.Interfaces;

// Here we have a page that sends a sms message. We have the ASP.NET ListBox control for
// message templates/ And we have 3 buttons "Add", "Remove" and "Edit". So we need to test // that appropriate events can be raised and the "Presenter" class (we use //(Model-View-Presenter" pattern) is subscibed to those events.

namespace MyProject.Tests.Presenters
{
[TestFixture]
public class SendMessagePresenterTest
{
[SetUp]
public void Setup()
{
mockery = new MockRepository();
e = new EventArgs();
sendMessageView = mockery.CreateMock(typeof (ISendMessageView), null) as ISendMessageView;
}


private MockRepository mockery;
private IEventRaiser raiseEvent;
private ISendMessageView sendMessageView;
private SendMessagePresenter sendMessagePresenter;
private EventArgs e;

[Test]
public void ShouldSubscribeToPageEvents()
{
// we have the list of objects of type IEventRaiser
List listToInvoke = new List();
using (mockery.Ordered())
{
//here we work with IEventRaiser interface of Rhino.Mocks. See the Rhino.Mocks //documentation for details
sendMessageView.AddTemplate += null;
// In this method we make some constraints and we're adding each call to list
PrepareEvent(listToInvoke);
sendMessageView.DeleteTemplate += null;
PrepareEvent(listToInvoke);
sendMessageView.ModifyTemplate += null;
PrepareEvent(listToInvoke);
}
mockery.ReplayAll();
sendMessagePresenter = new SendMessagePresenter(sendMessageView);
//here we invoke all recorded events. If your events have different arguments you can invoke // all events by index like this listToInvoke[1].Raise (null, new MyEventArgs());
foreach (IEventRaiser raiser in listToInvoke)
{
raiser.Raise(null, e);
}

mockery.VerifyAll();
}
private void PrepareEvent(ICollection listToInvoke)
{
LastCall.Constraints(Is.NotNull());
LastCall.IgnoreArguments();
//this is the event to invoke. We register it and then we're adding the event to raise to the //invocation list
raiseEvent = LastCall.GetEventRaiser();
listToInvoke.Add(raiseEvent);
}
}
}