Question

I'm developing an asp.net (classic) application trying to implement the MVP pattern using this example. In trying to unit test my presenter and using the following pattern, the psuedocode for which looks like so

//base view interface
public interface IView
{
    event EventHandler Init;

    event EventHandler Load;

    bool IsPostBack { get; }

    void DataBind();

    bool IsValid { get;}
}

//presenter psuedo code
public class SomePresenter
{
     public SomePresenter(ISomeDomainService service, IView someView)
     {
           ...
           //HOW DO WE TEST/VERIFY THAT THIS REGISTRATION OCCURS?
           someView.Init += OnInit;
           someView.Load += OnLoad;
     }
}
...
//consuming code that exercises the above code, that needs to be tested
var presenter = new SomePresenter(someDomainService, someView);

How do I verify that the presenter is doing what is expected i.e. registering for the Init and Load events? While this is easily done in the Phil Haack's example using Rhino mocks...

[Test]
public void VerifyAttachesToViewEvents()
{
    viewMock.Load += null;
    LastCall.IgnoreArguments();
    viewMock.PostSaved += null;
    LastCall.IgnoreArguments();
    mocks.ReplayAll();
    new PostEditController(viewMock, 
      this.dataServiceMock);
    mocks.VerifyAll();
}

... how can we do this using MOQ?

Was it helpful?

Solution

It would appear that this functionality is not currently available in moq, but may appear in a future version (I had a look in the 4.0.812.4 beta, but it doesn't seem to be there).

It may be worth asking the question, "why does SomePresenter need to subscribe to the View's Load and Init events?" Presumably it is because the SomePresenter class needs to respond to those events. So it might be better to use the Raise method on your Mock<IView> to raise the Load and Init events, and then assert that SomePresenter did the right thing in response to them.

OTHER TIPS

I know it's maybe too late for #Dilip, but this answer can be helpful for those who are trying to do the same. Here is the test class

public delegate void SubscriptionHandler<T>(string name, T handler);

public class SomePresenterTest
{
    [Test]
    public void Subscription_Test()
    {
        var someServiceMock = new Mock<ISomeDomainService>();
        var viewMock = new Mock<IView>();
        //Setup your viewMock here

        var someView = new FakeView(viewMock.Object);
        EventHandler initHandler = null;            
        someView.Subscription += (n, h) => { if ((nameof(someView.Init)).Equals(n)) initHandler=h; };

        Assert.IsNull(initHandler);

        var presenter = new SomePresenter(someServiceMock.Object, someView);

        Assert.IsNotNull(initHandler);
        Assert.AreEqual("OnInit", initHandler.Method?.Name);
    }
}

FakeView is a decorator implemented as follow (pay attention to Events:Init/Load{add;remove}):

public class FakeView : IView
{
    public event SubscriptionHandler<EventHandler> Subscription;
    public event SubscriptionHandler<EventHandler> Unsubscription;
    private IView _view;
    public FakeView(IView view)
    {
        Assert.IsNotNull(view);
        _view = view;
    }

    public bool IsPostBack => _view.IsPostBack;
    public bool IsValid => _view.IsValid;

    public event EventHandler Init
    {
        add
        {
            Subscription?.Invoke(nameof(Init), value);
            _view.Init += value;
        }

        remove
        {
            Unsubscription?.Invoke(nameof(Init), value);
            _view.Init -= value;
        }
    }
    public event EventHandler Load
    {

        add
        {
            Subscription?.Invoke(nameof(Load), value);
            _view.Init += value;
        }

        remove
        {
            Unsubscription?.Invoke(nameof(Load), value);
            _view.Init -= value;
        }
    }

    public void DataBind()
    {
        _view.DataBind();
    }
}

I spent some time with this question and the solution which I'm using in my project is:

Unit test:

// Arrange
TestedObject.Setup(x => x.OnEvent1());
TestedObject.Setup(x => x.OnEvent2());

// Act
TestedObject.Object.SubscribeEvents();
TestedObject.Raise(x => x.Event1 += null);
TestedObject.Raise(x => x.Event2 += null);

// Assert
TestedObject.Verify(x => x.OnEvent1(), Times.Once());
TestedObject.Verify(x => x.OnEvent2(), Times.Once());

Tested method:

this.Event1 += OnEvent1;
this.Event2 += OnEvent2;

So, first you have to mock the methods which you will assign the events, after you call the method which you want to test, and finally raise all subscribed events. If the event is really subscribed, you can check with Moq if the assigned method is called.

GLHF!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top