Moq - mock.Raise должно вызывать событие в тестируемом модуле без установки - PullRequest
30 голосов
/ 16 мая 2011

У меня есть класс докладчика, который присоединяет событие внедренного просмотра. Теперь я хотел бы проверить, правильно ли реагирует докладчик на событие.

Это интерфейс просмотра IView:

public interface IView 
{
    event EventHandler MyEvent;
    void UpdateView(string test);
}

Это представление, реализующее IView

public partial class MyView : IView
{
    public event EventHandler MyEvent;

    public MyView()
    {
        this.combo.SelectedIndexChanged += this.OnSelectedIndexChanged;
    }

    public void UpdateView(string test)
    {
        this.textBox.Text = test;
    }

    private OnSelectedIndexChanged(Object sender, EventArgs e)
    {
        if (this.MyEvent != null)
        {
            this.MyEvent(sender, e);
        }
    }
}

Это тестируемый докладчик:

public class MyPresenter
{
    private IView _view;
    public MyPresenter(IView view)
    {
        this._view = view;
        this._view.MyEvent += this.OnMyEvent;
    }

    private void OnMyEvent(Object sender, EventArgs e)
    {
        this._view.UpdateView();
    }
}

Это тестовое устройство тестирования MyPresenter:

[TestClass]
public class MyPresenterFixture()
{
    private MyPresenter testee;
    private Mock<IView> mockView;

    [TestMethod]
    public void ShouldReactOnMyEvent()
    {
        // arrange
        this.mockView = new Mock<IView>(MockBehavior.Strict);
        this.testee = new MyPresenter(this.mockView.Object);

        // act
        this.mockView.Raise(mock => mock.MyEvent += null); // this does not fire

        // assert and verify
        this.mockView.Verify(mock => mock.UpdateView(It.IsAny<string>());
    }
}

Я использую Moq 4. Можно ли делать то, что я хочу?

С наилучшими пожеланиями Yannik

Ответы [ 2 ]

60 голосов
/ 18 мая 2011

Вам не нужно передавать аргумент?Ваша подпись события - EvenHandler, которая
(object sender, EventArgs e).

this.mockView.Raise(mock => mock.MyEvent += null, new EventArgs());

Я никогда не использовал указанную вами перегрузку ... хотя она не выглядит корректной.*

3 голосов
/ 16 мая 2011

Вы объявили UpdateView () как принимающую строку, но у вашего вызова презентатора нет строкового аргумента (или по умолчанию):

Вызов:

private void OnMyEvent(Object sender, EventArgs e)
{
    this._view.UpdateView();
}

Объявление:

public void UpdateView(string test)
{
    this.textBox.Text = test;
}

Проверка:

mockView.Verify(mock => mock.UpdateView(It.IsAny<string>());

FWIW, я думаю, что событие, по вашему мнению, немного громоздко, простое изменение будет следующим:

public interface IView
{
    void UpdateText(string test);
}

public class MyPresenter
{
    private readonly IView _view;
    public MyPresenter(IView view)
    {
        _view = view;
    }

    private void SelectItem(string item)
    {
        _view.UpdateText(item);
    }
}

public partial class MyView : IView
{
    private readonly MyPresenter _presenter;

    public MyView()
    {
        _presenter = new MyPresenter(this);
        combo.SelectedIndexChanged += OnSelectedIndexChanged;
    }

    public void UpdateText(string test)
    {
        textBox.Text = test;
    }

    private OnSelectedIndexChanged(Object sender, EventArgs e)
    {
        _presenter.SelectItem(combo.SelectedItem);
    }
}

ТогдаВы можете просто проверить взаимодействие с представлением, не имея дополнительного события для обработки:

    presenter.SelectItem("Burrito!");

    mockView.Verify(mock => mock.UpdateView("Burrito!");
...