web-dev-qa-db-ja.com

Moq-mock.Raiseはセットアップを行わずにテスト済みユニットでイベントを発生させる必要があります

挿入されたビューのイベントを添付するプレゼンタークラスがあります。次に、プレゼンターがイベントに正しく反応するかテストします。

これは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を使用しています。自分のやりたいことを実行できますか?

よろしく

34
Yannik

引数を渡す必要はありませんか?イベントシグネチャはEvenHandlerです。
(object sender, EventArgs e)

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

ここで指定したオーバーロードは使用したことがありませんが、正しくないようです。

68
Anderson Imes

文字列を受け入れるように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!");
3
Ritch Melton