While working on The Regulator I came up with a class to help me test logic pertaining to events being thrown from the tested class (event throwing logic).
I tried to think what would be the easiest way to test such a thing. Simply registering for the events in your own fixture might be good enough if you don't have to check the values of the arguments being passed in the event ('wasCalled pattern') but when the time comes to check parameter values it gets pretty ugly fast.
I wanted to come up with code that looked like this:
[Test]
public void OnSomethingHappened_NoEventThrown()
{
ThrowerUnderTest test = new ThrowerUnderTest();
public void OnSomethingHappened_NoEventThrown()
{
ThrowerUnderTest test = new ThrowerUnderTest();
EventsVerifier verifier = new EventsVerifier();
verifier.ExpectNoEvent(test,"SomethingHappened");
test.OnSomethingHappened(false);
}
verifier.ExpectNoEvent(test,"SomethingHappened");
test.OnSomethingHappened(false);
}
[Test]
public void OnSomethingHappened_EventThrown()
{
ThrowerUnderTest test = new ThrowerUnderTest();
EventsVerifier verifier = new EventsVerifier();
verifier.Expect(test,"SomethingHappened");
test.OnSomethingHappened(true);
verifier.Verify();
}
verifier.Expect(test,"SomethingHappened");
test.OnSomethingHappened(true);
verifier.Verify();
}
Making this work was not easy. You basically need to create an event handler at runtime for the event requested, receive the event and check the parameters. I wanted to use some of my own code to do this but lucked out and had a great starting point with this very nice piece of code from CodeProject that helps you create a generic events handler for any method.
Once you have that, it's a pretty short way to make this work as part of a test suite. Which means, if you'd like to run code like the one above today, you can, by simply downloading this small zip file and using the class inside it. It comes with full unit tests, of course, to help you get up to speed on how it's supposed to work. There is also a small testing example there that looks a lot like the one you just saw here. It's pretty simple, and shouldn't be hard to add to your own project.
Note: Currently there is only support for testing one occurrence of the event (You can't make sure that it happens twice in a row, for example, without creating new verifier instances after each event is already raised)
comments and questions are welcome.