Today I was trying to wrap some code in some tests (I got lazy and did not create the tests first… shot me). What I was trying to ensure was that my event handlers I passed into a method were actually being wired up for usage. Now I searched around the net for a while to see if there was a elegant solution to this problem but I could not find one. Below is the solution I came up with. Mind you this may not be a great solution, hell it may just down right suck but it works for me.
First things first, her is the method i was trying to provide coverage for
public void GetAppointments( DateTime? from, DateTime? to,
EventHandler localRequestStarted,
EventHandler remoteRequestStarted,
EventHandler
As you can see there are 3 lines in the above code where the passed in EventHandlers are being attached. I wanted to ensure this. But what you may also see is that I have no direct access to the dataRequest object which is being created in this method. That is where our handy rhino mocks library comes in. With Rhino Mocks I am able to get the pointer to the various values which are passed into methods. Check out the test below and you will see how this is done.
My unit test
[Test]
public void GetAppointments_WhenCalled_EnsureWillWireupEventsCorrectly()
{
var dataManager = MockRepository.GenerateMock<IDataManager>();
var sessionManager = MockRepository.GenerateMock<ISessionManager>();
var currentUser = new CurrentUser();
sessionManager.Stub( x => x.GetValue<CurrentUser>() ).Return( currentUser );
var provider = new AppointmentProvider( dataManager, null, sessionManager, null );
bool localWired = false, remoteWired = false, requestFinishedWired = false;
EventHandler<LocalRequestStartedEventArgs> localRequest = ( s, arg ) => { localWired = true; };
EventHandler<RemoteRequestStartedEventArgs> remoteRequest = ( s, arg ) => { remoteWired = true; };
EventHandler<RequestFinishedEventArgs<object>> requestFinished = ( s, arg ) => { requestFinishedWired = true; };
provider.GetAppointments( DateTime.Now, DateTime.Now, localRequest, remoteRequest, requestFinished );
IList<object[]> argumentsForCallsMadeOn = dataManager.GetArgumentsForCallsMadeOn( x => x.Fetch( Arg<DataRequest>.Is.Anything ) );
var dataRequest = (AppointmentDataRequest)argumentsForCallsMadeOn[ 0 ][ 0 ];
dataRequest.RaiseLocalRequestStarted();
dataRequest.RaiseRemoteRequestStarted();
dataRequest.RaiseDataRequestFinished( DataRequestType.UserLogin, DataRequestResult.Unknown, null, null );
Assert.That( localWired, Is.True );
Assert.That( remoteWired, Is.True );
Assert.That( requestFinishedWired, Is.True );
}
As you can see this test has a lot going on, but let me explain some of this for you.
1) First thing we need to do is create a few local variables which will hold the state of the event firing
2) Next we want to create local copies of our event delegates in order to push them into our method
3) Next is time for the Rhino Mock magic. Notice how I am calling the GetargumentsForCallsMadeOn() method. This is a method in Rhino Mocks which allows me to reach into the call stack and pull out the values which were pushed into a method when it was called. I then cast the argument i want to its native type.
4) In order to ensure the events were wired up I need to call the various ‘raise’ methods in order to trigger them. Doing this should cause my local state holders for the events to be changed and this is what we actually want to ensure
5) Ensure the event state variables were set to true.
There you have it, a simple (well kinda) way to ensure that your events have been registered correctly in your code.
Till next time,
Posted
08-24-2010 6:04 AM
by
Derik Whittaker