Moq - mock.Raise 应该在测试单元中引发事件,而无需安装

发布于 2024-11-08 00:42:46 字数 1666 浏览 0 评论 0原文

我有一个演示者类,它附加了注入视图的事件。 现在我想测试演示者对事件的正确反应。

这是视图接口 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>());
    }
}

我正在使用最小起订量 4。可以做我想做的吗?

I have a presenter class, that attaches an event of the injected view.
Now I would like to test the presenter reacting correctly to the event.

This is the view interface IView:

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

This is the view implementing 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);
        }
    }
}

This is the presenter under test:

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

This is the test fixture testing 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>());
    }
}

I am using Moq 4. Is it possible to do what I want?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

红焚 2024-11-15 00:42:46

不需要通过论证吗?您的事件签名是 EventHandler,即
(对象发送者,EventArgs e)

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

我从未使用过您在此处指定的重载...不过,它似乎不正确。

Don't you need to pass the argument? Your event signature is EventHandler, which is
(object sender, EventArgs e).

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

I've never used the overload you've specified here... it doesn't seem correct, though.

夏有森光若流苏 2024-11-15 00:42:46

您已将 UpdateView() 声明为接受字符串,但您的演示者调用没有字符串参数(或默认值):

Inspiration:

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

Declaration:

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

Verification:

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!");

You've declared UpdateView() as accepting a string, but your presenter invocation does not have a string argument (or default):

Invocation:

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

Declaration:

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

Verification:

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

FWIW, I think the event in your view is a bit cumbersome, a simple change would be to:

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

Then you could just verify the interaction with the view without having an additional event to deal with:

    presenter.SelectItem("Burrito!");

    mockView.Verify(mock => mock.UpdateView("Burrito!");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文