Я использую Moq, xUnit и Prism 4. Целью моего модульного теста является запуск события и подтверждение того, что свойство изменилось в моей модели просмотра в соответствии с значением из событие. Этот тест, кстати, выходит из строя (Ожидаемый: 5, Actual: 0):Я не понимаю различия в этих модульных тестах
// Version One
[Fact]
public void Should_set_DayCount_on_DayCountChangedEvent()
{
var eaMock = new Mock<IEventAggregator>();
eaMock.SetupCurriculumEvents(); // see below
var vm = new CurriculumItemViewModel(eaMock.Object, _systemStatus.Object);
vm.Load(_newItem);
var dayCount = 5;
eaMock.Object.GetEvent<DayCountChangedNotification>().Publish(dayCount);
Assert.Equal(dayCount, _vm.DayCount);
}
Я устал от создания моей агрегатор события издевается везде, поэтому я создал метод расширения, чтобы сделать грязную работу для меня:
public static void SetupCurriculumEvents(this Mock<IEventAggregator> eaMock)
{
eaMock.Setup(ea => ea.GetEvent<DayCountChangedNotification>())
.Returns(new DayCountChangedNotification());
// lots of other "notification" events here as well
}
Тогда я понял, что я создаю новое событие каждый раз, когда он извлекается из фиктивного агрегатора событий, поэтому Subscribe()
на один экземпляр (в VM) не на тот же экземпляр Publish(dayCount)
в моем тесте.
Ну, мне кажется, давайте всегда использовать один и тот же объект (путем перезаписи метод обслуживания внутреннего Setup()
для этого события), и мы будем хорошо:
// Version Two
[Fact]
public void Should_set_DayCount_on_DayCountChangedEvent()
{
var dayCountChangedEvent = new DayCountChangedNotification();
var eaMock = new Mock<IEventAggregator>();
eaMock.SetupCurriculumEvents(); // still need this for all the other events
// overwrite the setup from the extension method
eaMock.Setup(ea => ea.GetEvent<DayCountChangedNotification>())
.Returns(dayCountChangedEvent);
var vm = new CurriculumItemViewModel(eaMock.Object, _systemStatus.Object);
vm.Load(_newItem);
var dayCount = 5;
dayCountChangedEvent.Publish(dayCount);
Assert.Equal(dayCount, _vm.DayCount);
}
... который также не зрелищно.
По какой-то причине, я решил попробовать рефакторинга метод расширения, (и вернулся тест блока обратно в первой версии):
public static class MockingExtensions
{
private static DayCountChangedNotification DayNotification = new DayCountChangedNotification();
public static void SetupCurriculumEvents(this Mock<IEventAggregator> eaMock)
{
eaMock.Setup(ea => ea.GetEvent<DayCountChangedNotification>())
.Returns(DayNotification);
// etc...
}
}
... который, на мой взгляд, это в основном то же самое - Я всегда возвращаю тот же экземпляр события.
Кикер: Этот тест проходит.
Это здорово и все, но я не понимаю почему он проходит - и если я не понимаю, почему он проходит, то я действительно не знаю, правильно это или нет.
Принято ответ должен объяснить две вещи:
- Почему переработан метод расширения с помощью статического экземпляра пройти?
- Почему нет версии Two pass?
Объявление статического поля класса не совпадает с локальной переменной. Выполнял ли этот тест только этот тест или выполнял этот тест во время теста с другими тестами? Какова реализация DayCountChangedNotification? –
'DayCountChangedNotification' - это просто пустой класс, который наследуется от класса Prism' CompositePresentationEvent '. Тест проводился как в одиночном режиме, так и в совместном прогоне с другими тестами - результаты были согласованы. –