#c# #events #tdd #moq #mvp
#c# #Мероприятия #tdd #moq #mvp
Вопрос:
У меня есть класс presenter, который прикрепляет событие введенного представления. Теперь я хотел бы проверить правильность реакции докладчика на событие.
Это интерфейс просмотра 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. Возможно ли сделать то, что я хочу?
Ответ №1:
Разве вам не нужно передавать аргумент? Ваша подпись события EventHandler
, которая
(object sender, EventArgs e)
.
this.mockView.Raise(mock => mock.MyEvent = null, new EventArgs());
Я никогда не использовал перегрузку, которую вы указали здесь… однако это не кажется правильным.
Комментарии:
1. 1. Или передать в EventArgs.Empty . Вам нужно передать любые параметры, кроме отправителя, в качестве аргументов в Mock.Raise. Ссылки madcoderspeak.blogspot.com/2010/01 / … code.google.com/p/moq/wiki/QuickStart
2. Почему мы используем mock. MyEvent = null?? пожалуйста, объясните, поскольку я новичок.
3. @BhoopathiReddy : событие может отображаться только в левой части = или -=. Смотрите CS0079
Ответ №2:
Вы объявили UpdateView() как принимающий строку, но ваш вызов presenter не имеет строкового аргумента (или по умолчанию):
Вызов:
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>());
Черт возьми, я думаю, что событие, на ваш взгляд, немного громоздкое, простым изменением было бы:
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!");
Комментарии:
1. Привет, Ритч, спасибо за ваш отзыв. Я видел, что в методе presenters private аннулируется OnMyEvent(отправитель объекта, EventArgs e) { this._view . UpdateView(); } входные данные для UpdateView отсутствуют. К сожалению, ваш подход у нас не работает, потому что мы реализуем чисто пассивное представление, и представление никогда не знает своего докладчика. Приветствия