Ayende @ Wiki

Edit

Overview

The purpose of this example is to show, as tersely as possible, how to raise events on a mocked interface and test the result. The example uses a very simple view interface and presenter class to simulate a very basic MVP design.

This document shows a test method written in Record/Replay syntax and in Arrange/Act/Assert syntax. The two versions are functionally equivalent.

The following code defines:
  • A delegate with a non-"standard" event signature to demonstrate that any event can be raised.
  • A Presenter class that responds to the event fired by the view and subsequently modifies the view's state.

Rhino's job in this example is to ensure that the event was fired and that the view's state was modified correctly. Notice that the event handler in Presenter is private, so Rhino cannot access it directly. So Rhino has to ensure that the call to SetResult() was made and that it contains the correct values.

Note that this example does NOT require a special flag on the Presenter class to reflect that an event was called.

Edit

Production Code

  public delegate void FooDelegate(string bar);

public interface IView { double Result { get; } void SetResult(double value);

event FooDelegate Foo; }

public class Presenter { private readonly IView _view;

public Presenter(IView view) { _view = view; view.Foo += view_Foo; }

private void view_Foo(string bar) { var result = Convert.ToDouble(bar); _view.SetResult(result); } }


Edit

Record/Replay

    [Test]
    public void RR()
    {
      var mockery = new MockRepository();
      var view = mockery.DynamicMock<IView>();
      IEventRaiser raiser;

// record the expectations using(mockery.Record()) { view.Foo += null; // expect event subscribers LastCall.IgnoreArguments(); // always needed // optionally use: LastCall.Constraints(Is.NotNull());

raiser = LastCall.GetEventRaiser(); // get the event raiser

view.SetResult(5); // expect view.SetResult(5) to be called }

// run and verify using(mockery.Playback()) { new Presenter(view); // subscribe to the event raiser.Raise("5"); // run the operation - emulate the view firing the event } }


Edit

Arrange/Act/Assert

    [Test]
    public void AAA()
    {
      // arrange
      var view = MockRepository.GenerateMock<IView>();
      new Presenter(view); // subscribe to the event

// act view.GetEventRaiser(v => v.Foo += null).Raise("5");

// assert view.AssertWasCalled(v => v.SetResult(Arg<double>.Is.Equal(5d))); }


Edit

Additional Notes

  • When using the Arg<T> constraint, make sure the type passed to Equal() is exactly right. Use Arg<double>.Is.Equal(5d)) and not Arg<double>.Is.Equal(5)).

  • In both versions, the Raise() method is not strongly typed.

ScrewTurn Wiki version 2.0 Beta. Some of the icons created by FamFamFam.