Ich verwende Moq, XUnit und Prism 4. Mein Unit Test Ziel ist es, ein Ereignis auszulösen und zu bestätigen, dass eine Eigenschaft in meinem View-Modell geändert hat, um den Wert von entsprechen das Ereignis. Dieser Test, der übrigens nicht (Erwartet: 5, Aktuell: 0):Ich verstehe nicht den Unterschied in diesen Unit-Tests
// 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);
}
Ich habe genug von meinem Event Aggregator mock überall einrichten, so dass ich erstellt eine Erweiterungsmethode, die schmutzige Arbeit zu tun für mich:
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
}
Dann erkannte ich, dass ich jedes Mal ein neues Event bin zu schaffen es aus dem Mock Ereignis-Aggregator, so dass die Subscribe()
auf eine Instanz (in der VM) ist abgerufen wird nicht auf der gleichen Instanz wie die Publish(dayCount)
in meinem Test.
Nun, mir scheint, wollen wir immer nur das gleiche Objekt verwenden (durch die Erweiterung Methode des Setup()
für dieses Ereignis überschreiben) und wir werden gut sein:
// 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);
}
... die auch spektakulär ausfällt.
Aus irgendeinem Grund habe ich beschlossen, Refactoring die Erweiterungsmethode, um zu versuchen, (und kehrte das Gerät Test Version zurück One):
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...
}
}
..., die mir in den Sinn, im Grunde ist die gleiche Sache - Ich gebe immer dieselbe Instanz des Ereignisses zurück.
Hier ist der Kicker: dieser Test besteht.
Das ist großartig und alles, aber ich verstehe nicht warum es passiert - und wenn ich nicht verstehe, warum es vorbei ist, dann weiß ich nicht wirklich, ob es richtig ist oder nicht.
akzeptierte Antwort braucht zwei Dinge zu erklären:
- Warum die Refactoring-Extension-Methode mit der statischen Instanz übergeben?
- Warum wird Version zwei nicht bestanden?
Das Deklarieren eines statischen Klassenfelds ist nicht dasselbe wie eine lokale Variable. Haben Sie diesen Test nur ausgeführt oder haben Sie diesen Test während eines Testlaufs mit anderen Tests ausgeführt? Was ist die Implementierung von DayCountChangedNotification? –
'DayCountChangedNotification' ist nur eine leere Klasse, die von Prisms 'CompositePresentationEvent' -Klasse erbt. Der Test wurde sowohl als Einzellauf als auch als gemeinsamer Lauf mit anderen Tests durchgeführt - die Ergebnisse waren konsistent. –