# Friday, April 27, 2007

Phil Haack gives an excellent example of how to test a registration to event while implementing MVP pattern (via Rhino Mocks). If you did not read it yet, take a pause for 2 minutes and give it a look; It is worth it, I promise.

The only thing that bothers me in the example is that the need to assert the triggering of the event kind of spoiled the code. I think that in those scenarios, it's much better to use some sort of Stub and override the class under test in order to keep the it cleaner. So instead of having this code:

public class Presenter
{
   IView view;
   public Presenter(IView view)
   {
      this.view = view;
      this.view.Load += new EventHandler(view_Load);
   }

   public bool EventLoaded
   {
      get { return this.eventLoaded; }
      set { this.eventLoaded = value; }
   }

   bool eventLoaded;

   void view_Load(object sender, EventArgs e)
   {
      this.eventLoaded = true;
   }
}


I would have created something like this:

public class Presenter
{
   IView view;
   public Presenter(IView view)
   {
      this.view = view;
      this.view.Load += new EventHandler(view_Load);
   }

   protected virtual void view_Load(object sender, EventArgs e)
   {
       // production code here
   }
}


// This will go in the PresenterTests class
public class TestablePresenter : Presenter
{
   public bool WasEventLoaded = false;
   protected override void view_Load(object sender, EventArgs e)
   {
       WasEventLoaded = true;
   }
}


Now we can create an instance of TestablePresenter and Assert the WasEventLoaded field.
My guess is that Phil actually did something like this in his project and merely wanted to show an example, but I still thought it was important enough to demonstrate this separation as I firmly believe we must make sure that our need for tests will not actually hurt the design.

.NET | TDD
« Fluent Interfaces - Let the API tell the story  | Main |   How to measure a skilled developer »
Friday, April 27, 2007 11:38:14 PM (Jerusalem Standard Time, UTC+02:00)
Exactly. I wouldn't have that property in my base Presenter class. The idea was basically that the point of subscribing to an event is that *Something* happens when the event is handled. You just want to assert that whatever it is you expect to happen when the event is raised does indeed happen.

In this case, I just set some boolean as an example. Your approach tests that the event was raised, which is good. But it doesn't test that the original Presenter did what it was supposed to do in response to the event.

Really, that should probably be two separate tests now that I think of it. :) Great critique though!
Saturday, April 28, 2007 9:30:15 AM (Jerusalem Standard Time, UTC+02:00)
Thanks for your comment Phil.
You're right, it's merely an interaction test. Now that we have that, we can test the actual implementation of view_Load by itself and we're covered.
Comments are closed.