Sto usando Reactive Extensions for .NET (Rx) per esporre eventi come IObservable<T>
. Voglio creare un test unitario in cui dichiaro che un particolare evento è stato licenziato. Ecco una versione semplificata della classe Voglio testare:Test di unità per un evento utilizzando le estensioni reattive
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();
}
}
Ovviamente i miei veri classi sono più complesse. Il mio obiettivo è verificare che l'esecuzione di alcune azioni con la classe sottoposta a test porti a una sequenza di eventi segnalati sullo IObservable
. Fortunatamente le classi che voglio testare implementano IDisposable
e chiamando OnCompleted
sull'oggetto quando l'oggetto è disposto rende molto più facile testare.
ecco come lo prova:
// Arrange
var classUnderTest = new ClassUnderTest();
var eventFired = false;
classUnderTest.SomethingHappened.Subscribe(_ => eventFired = true);
// Act
classUnderTest.DoSomething();
// Assert
Assert.IsTrue(eventFired);
Utilizzando una variabile per determinare se un evento viene generato non è male, ma in scenari più complessi mi può essere utile per verificare che una particolare sequenza di eventi sono licenziato. È possibile senza semplicemente registrare gli eventi nelle variabili e poi fare asserzioni sulle variabili? Poter usare una sintassi fluente simile a LINQ per fare asserzioni su un IObservable
si spera che renderebbe il test più leggibile.
BTW, penso che avere una variabile sia perfettamente buona. Il codice sopra è facile da leggere, il che è molto importante. La risposta di @ PL è bella ed elegante, ma devi sforzarti per capire cosa sta succedendo ... Forse trasformarlo in un'estensione FailIfNothingHappened() –
@Sergey Aldoukhov: Sono d'accordo, ma la risposta di PL mi ha insegnato come posso usare ' Materializzare' per ragionare su come si comporta il mio 'IObservable'. E per i test più complessi che utilizzano le variabili per catturare ciò che è successo potrebbe essere più difficile da capire. Inoltre, la creazione di un'estensione come suggerito probabilmente renderà più facile capire cosa sta succedendo. –
Ho modificato la mia domanda per rendere più chiaro ciò che voglio. –