J'utilise Reactive Extensions for .NET (Rx) pour exposer des événements sous la forme IObservable<T>
. Je veux créer un test unitaire où j'affirme qu'un événement particulier est déclenché. Voici une version simplifiée de la classe que je veux tester:Test d'unité pour un événement à l'aide d'extensions réactives
public sealed class ClassUnderTest : IDisposable {
Subject<Unit> subject = new Subject<Unit>();
public IObservable<Unit> SomethingHappened {
get { return this.subject.AsObservable(); }
}
public void DoSomething() {
this.subject.OnNext(new Unit());
}
public void Dispose() {
this.subject.OnCompleted();
}
}
Évidemment, mes vraies classes sont plus complexes. Mon but est de vérifier que l'exécution de certaines actions avec la classe testée conduit à une séquence d'événements signalés sur le IObservable
. Heureusement, les classes que je veux tester implémentent IDisposable
et l'appel OnCompleted
sur le sujet lorsque l'objet est disposé rend beaucoup plus facile à tester.
Voici comment je teste:
// Arrange
var classUnderTest = new ClassUnderTest();
var eventFired = false;
classUnderTest.SomethingHappened.Subscribe(_ => eventFired = true);
// Act
classUnderTest.DoSomething();
// Assert
Assert.IsTrue(eventFired);
En utilisant une variable pour déterminer si un événement est déclenché est pas trop mal, mais dans des scénarios plus complexes je veux vérifier qu'une séquence particulière d'événements sont mis à la porte. Est-ce possible sans simplement enregistrer les événements dans les variables et ensuite faire des assertions sur les variables? La possibilité d'utiliser une syntaxe proche de LINQ pour faire des assertions sur un IObservable
rendrait le test plus lisible.
BTW, je pense avoir une variable est parfaitement bien. Le code ci-dessus est facile à lire, ce qui est le plus important. La réponse du @ PL est belle et élégante, mais vous devez essayer de comprendre ce qui se passe ... Peut-être le transformer en extension FailIfNothingHappened() –
@Sergey Aldoukhov: Je suis d'accord, mais la réponse de PL m'a appris comment utiliser ' Matérialiser »pour raisonner sur le comportement de mon« IObservable ». Et pour des tests plus complexes utilisant des variables pour capturer ce qui s'est passé, il peut être plus difficile à comprendre. En outre, créer une extension comme vous le suggérez facilitera probablement la compréhension de ce qui se passe. –
J'ai modifié ma question pour clarifier ce que je veux. –