Verifying event registration using Moq

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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The moq 4.13 introduced this feature. Now it is possible to verify if addremove has been invoked. Therefore four new methods have been introduced:

  1. SetupAdd
  2. SetupRemove
  3. VerifyAdd
  4. VerifyRemove

Example

var mock = new Mock<IAdder<EventArgs>>();
mock.SetupAdd(m => m.Added += (sender, args) => { });

mock.Object.Added += (sender, args) => { };
mock.Object.Added += (sender, args) => { };

mock.VerifyAdd(m => m.Added += It.IsAny<EventHandler>(), Times.Exactly(2));

NB: Notice that in order to verify at least one setup should be added. The reason is to keep backward compatibility with the older version of moq.

Method 2

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.

Method 3

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();
    }
}

Method 4

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!


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x