Проверка регистрации события с помощью Moq - PullRequest
22 голосов
/ 16 сентября 2009

Я разрабатываю приложение asp.net (classic), пытающееся реализовать шаблон MVP , используя этот пример . При попытке выполнить модульное тестирование моего докладчика и с использованием следующего шаблона, psuedocode для которого выглядит так

//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);

Как проверить, что докладчик делает то, что ожидается, то есть регистрируется для событий Init и Load? Хотя это легко сделать в примере Фила Хаака с использованием насмешек Rhino ...

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

... как мы можем сделать это с помощью MOQ?

Ответы [ 3 ]

14 голосов
/ 16 сентября 2009

Может показаться, что эта функция в данный момент недоступна в moq, но может появиться в будущей версии (я посмотрел бета-версию 4.0.812.4, но ее там нет ).

Возможно, стоит задать вопрос: «Почему SomePresenter нужно подписываться на события Load и Init View?» Предположительно это потому, что класс SomePresenter должен реагировать на эти события. Поэтому может быть лучше использовать метод Raise на вашем Mock<IView>, чтобы вызвать события Load и Init, а затем утверждать, что SomePresenter поступил правильно в ответ на них.

1 голос
/ 14 января 2017

Я знаю, что может быть слишком поздно для #Dilip, но этот ответ может быть полезен для тех, кто пытается сделать то же самое. Вот тестовый класс

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 - это декоратор, реализованный следующим образом (обратите внимание на События: 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();
    }
}
0 голосов
/ 17 июля 2013

Я провел некоторое время с этим вопросом, и решение, которое я использую в своем проекте:

Юнит-тест:

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

Метод испытания:

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

Итак, сначала вы должны смоделировать методы, которым вы будете назначать события, после того, как вы вызовете метод, который вы хотите проверить, и, наконец, вызвать все подписанные события. Если событие действительно подписано, вы можете проверить с помощью Moq, вызван ли назначенный метод.

GLHF!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...