views:

115

answers:

3

Im fully aware of the "problem" with static event handlers from a GC perspective so i'm not looking for advice on "DONT use static events" or anything like that, in my scenario this isnt a concern.

I have a static class which has an event declared

public static event EventHandler<MyEventArgs> FilePickedUpFromStorage;

i have a client service that subscribes to this event and im wanting to Mock/test the static event being fired with a fake MyEventArgs to assert the handling works as specified, at the client. Straightforwards stuff.... the problem i have is that this event is static on a static class. im looking for some solid guidance on the best approach to dealing with this, if anyone can offer any help. Changing the static event is not an option, wrapping it or any other magic is...

Thanks!

+3  A: 

Since you specifically states that it is not an option to change the event from static to instance, you could take a look at TypeMock Isolator. It is a mocking framework that works by rewriting IL code necessary to mock stuff that could not otherwise be mocked. It is not the best solution IMO, but it will help you do want you want in this situation without changing the code.

Brian Rasmussen
thanks brian, i have looked at typemock and its a great option in this scenario, but i have to live with the tools i have... Rhino Mocks and NUnit. by the way, are you of the belief that static events should never be used ever ?
Matt
@Matt: Some people say that TypeMock is too clever for its own good, and they sort of have a point in that it will allow you to take a shortcut where you would probably be better off changing the code. However, sometimes we don't have that option and in those cases TypeMock can be a big help. Having said that, I personally prefer to make the code testable and statics can make that harder.
Brian Rasmussen
A: 

You are testing your class's response to receiving an event. So presumably you are concerned about the bahviour of a method on your class which receives the event

public void OnHandler1(object sender, MyEventArgs e)

So in your tests don't you just call that method directly? You might need to mock the sender object, but presumbly he is of a known type because you're casting him to use him, so you know what to mock.

In other words for testing your class you may not actually need the real source of events at all.

djna
The idea is ok, to have a public method on the tested class to avoid the event at all - but event handlers should not be public.
Stefan Steinegger
Interesting, reference material I found http://www.developerfusion.com/article/2137/event-handling-in-net-using-c/3/ did have them as public.
djna
+2  A: 

You could keep the static event for "legacy compatibility" and provide a better structure for new (and testable) code.

// legacy
public static class OldClass
{
  public static event EventHandler<MyEventArgs> FilePickedUpFromStorage;
}

// new interface for testability
public interface IBraveNewWorld
{
  event EventHandler<MyEventArgs> FilePickedUpFromStorage;
}

// new implementation
public class BraveNewWorld : IBraveNewWorld
{
  public event EventHandler<MyEventArgs> FilePickedUpFromStorage;
  public BraveNewWorld()
  {
    // MyHandler forwards the event
    OldClass.FilePickedUpFromStorage += MyHandler;
  }
}

// new testable user of the event.
public class TestableClass
{
  // here you can pass a mock or just an instance of BraveNewWorld
  public TestableClass(IBraveNewWorld x)
  {

  }
}
Stefan Steinegger
thanks stefan, this is very close to what im experimenting with at the moment, not a fan of introducing the indirection but maybe thats just me.
Matt
It's never funny to deal with legacy code. There is always a trade-off between keeping legacy code and reduce amount of work and the to enhance current framework to make new code better then the old is. Good luck.
Stefan Steinegger