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?
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.
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!");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With