Artykuł ten jest częścią serii artykułów na temat Programowania reaktywnego.
Zapraszam na GitHub-a.
Tematy
- Wstęp
- Zabawa z czasem - Timer
- Kto za tym stoi? - Scheduler
- Nie zapominaj - Subscribe
- Zabawa z czasem - Interval
- Zabawa z czasem - Buffer
- Zabawa z czasem - Delay
- Zabawa z czasem - Sample
- Zabawa z czasem - Throttle
- Zabawa z czasem - Timestamp/TimeInterval
- Tworzymy dane - Generators
- Tworzymy dane - Własna klasa publikująca
- Marudzimy - Skip
- Marudzimy - Take
- Łap To! - ConsoleKey
- Kombinatorzy - Concat
- Kombinatorzy - Repeat
- Kombinatorzy - Start With
- Kombinatorzy - Ambiguous
- Kombinatorzy - Merge
- Kombinatorzy - Zip
- Kombinatorzy - Switch
- Kombinatorzy - When-And-Then
- Kombinatorzy - Combine Latest
- Transformers - Select
- Transformers - OfType and Cast
- Transformers - Metadata
- Bileciki do kontroli - Unit Tests of Interval
- Bileciki do kontroli - Unit Tests of Observer Interval
- Bileciki do kontroli - Unit Tests of Create Cold/Hot Observable
- Szpryca - AutoFac
Wstęp
Wszystko super i fajnie ale gdzie są testy? Co zrobić by przetestować taki strumień zasilany przez Observable.Interval? Przecież testy będą trwały wieczność… Jest na to rada: przeczytaj post do końca;) Ale na początek warto było by wyposażyć się w dodatkowe narzędzia:
- Install-Package Shouldly - by asercje były milsze dla oka,
- Install-Package Microsoft.Reactive.Testing - wymagana biblioteka do testowania Rx-owatych,
- Install-Package xUnit - bez tej paczuszki to ani rusz w testy;).
TestScheduler
Jak to w testach bywa, trzeba czasem oszukać system i posłużyć się udawaczami. Tak jest i w przypadku testów.
Aby nie odczuć bólu testowania np.: operatora Interval należy zakupić DeLorean-a. I między poszczególnymi porcjami dostarczanymi przez dystrybutora odbyć krótką podróż w czasie…
Jest też inne wyjście prostsze. Po prostu należy użyć schedulera: TestScheduler. Jak tego można dokonać bez posiadania własnego DeLorean-a ukazałem w metodzie InitializeStream.
Przykład oczywiście poniżej oraz w pełnej krasie na GitHub-ie.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class IntervalTestsFixture
{
#region arrange
private IObservable<long> _observableInterval;
private TestScheduler _testScheduler;
private IList<long> _expectedSequence;
public void PrepareStream(int count)
{
InitializeStream(count);
InitializeExpectedValues(count);
}
private void InitializeStream(int count)
{
_testScheduler = new TestScheduler();
var period = TimeSpan.FromSeconds(1);
_observableInterval = Observable
.Interval(period, _testScheduler)
.Take(count);
}
Jak można było dojrzeć w klasie IntervalTestsFixture zawartych jest więcej interesujących linijek. Dzięki tej klasie możemy wyzbyć się balastu ciężkich do zrozumienia testów jednostkowych. [Chwała Ci za to Procencie:)].
To może coś przetestujemy. Proszę to ładna klaska zawierająca jedną metodę oraz jej wariacje. Testującą czy Interval faktycznie zwraca co ma zwrócić.
Jak widać głównie widzimy to co ma być testowane, a nie to że sąsiadka z naprzeciwka przechadza się nago wieczorami w oknie. Tym się zajmuje wspomniana IntervalTestsFixture. Co by nas zbytnie nie rozpraszało w testowaniu.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class IntervalTests
{
[Theory]
[InlineData(0)]
[InlineData(10)]
[InlineData(100)]
[InlineData(1000)]
[InlineData(100000)]
public void return_sequence_of_numbers__when__subscribe_to_interval_observable_stream(int count)
{
//arrange
_fixture.PrepareStream(count);
//act
var result = act();
//assert
_fixture.assert__sequence_of_numbers(result);
}
private ICollection<long> act()
{
return _fixture.act();
}
Ładna co nie? Ale to moja:p Napiszcie sobie sami…
Na koniec smaczek co act. Do testów potrzebne są wyniki, dlatego też w miejscu gdzie testujemy funkcjonalność zapisujemy się na strumień, i pakujemy wszystko do listy.
1
2
3
4
5
6
7
8
9
public ICollection<long> act()
{
var actualValues = new List<long>();
_observableInterval.Subscribe(actualValues.Add);
_testScheduler.Start();
return actualValues;
Potem Shouldly sprawdzi czy wszystko jest prawidłowo. Jak nie to poczęstuje nas odpowiednim i gorzkim komunikatem.
Zakończenie
Testowanie to bardzo ważny aspekt wytarzania oprogramowania. Dlatego zapewne do napisania mam jeszcze wiele postów o podobnej tematyce. Także w kontekście Rx-ów. Jednak na dzisiaj koniec tego dobrego piąteczek, niedługo koniec wyzwania. A ja już czuję ogromną satysfakcję, a co dopiero w Niedzielę:)
Jest to post wchodzący w skład podjętego wyzwania ogłoszonego przez MIROBURN we vlogu z dnia 3 lutego 2018 roku.
Celem wyzwania jest systematyczne działanie w ciągu 30 dni.
Postanowiłem pisać post dziennie o tematyce Programowania Reaktywnego dla platformy .NET.
Wszelkie źródła związane z postami znajdują się na repozytorium GitHub.
Stan obecny wyzwania: 30 z 30 dni.
Referencje:
- MSDN - Getting Started with Rx,
- MSDN - Reactive Extensions,
- 101 Rx Samples,
- ReactiveX,
- Code Project,
- GitHub
Wcześniejszy: Programowanie Reaktywne - Transformers - Metadata
Następny: Programowanie Reaktywne - Bileciki do kontroli - Unit Tests of Observer Interval