Verifying event registration using Moq Verifying event registration using Moq asp.net asp.net

Verifying event registration using Moq


The moq 4.13 introduced this feature. Now it is possible to verify if add\remove 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.


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.


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