views:

233

answers:

3

I tend to veer towards the opinion that only public interfaces should be tested, thereby covering testing of private procedures. However, an interesting question arose yesterday - should one test event handlers? My gut instinct is that logic should be stored in self-contained procedures invoked by the handlers themselves, but this is subjective and would more than likely result in private procedures rather than public ones that are being tested. Should I be unit testing event handlers and, if so, what are the best practices for doing so?

A: 

I believe event handlers should be tested. If you follow the normal pattern of doing something along the lines of:

public event EventHandler MyEvent;
protected void OnMyEvent()
{
    // Raise MyEvent here
}

Then testing of MyEvent is effectively part of the test of OnMyEvent, since the only "test" you will do is to verify that the event is raised properly.

Typically, testing an event means subscribing to it, and doing something that should (or should not) raise it.

Reed Copsey
A: 

I read your question and didn't know if you were asking about the body of the handler or whether or not the handler was actually bound correctly to handle the event.

As you say, the body of the handler should simply call another method, which you've already tested (if it's public).

I generally don't unit test the wiring of event handlers unless they're going to be changing at runtime, as I'm very likely to catch in my developer and integration testing event handlers that don't bind/unbind at runtime, aren't wired up, and should have been.

lance
+1  A: 

In no way am I going to say someone is "wrong" for unit testing an event handler. Personally I'd go with the philosophy of "test what might break" and wouldn't.

The main thing I've seen consistently wrong with event code is something unit tests won't catch - the "On" method will just be:

if (MyEventHandler != null)
    MyEventHandler(this, e);

This has a race condition; MyEventHandler should be assigned to a variable before the null check.

The second common error is people passing null for the "e" event data parameter; this could be tested.

If you don't own a copy of Framework Design Guidelines 2nd Ed. by Cwalina & Abrams, buy it now. It will tell you how to write event code correctly every time, how to write the Dispose Pattern properly, and many other things.

TrueWill