Testowanie RxJS z użyciem Marbles
Jakub Szafraniec
Jakub Szafraniec
Senior JavaScript Developer



Agenda
- W czym jest problem?
- Teoria
- Praktyka
W czym jest problem?
let result; service.getSomething$().subscribe((value) => { result = value; });
it('should ....', () => {
tick(100); expect(result).toEqual(A);
tick(300); expect(result).toEqual(B);
tick(500); expect(result).toEqual(C);
350?
START -> 100ms A 300ms B 500ms C -> END
fakeAsync(
Wady fakeAsync
- Brak precyzyjnej kontroli czasu
- Brak kontroli początku/zakończenia subskrypcji
- Skomplikowane testowanie obsługi błędów
- Dużo boilerplate
RxJS Marbles
it('generate the stream correctly', () => { testScheduler.run(helpers => { }); });
const e1 = cold(' -a--b--c---|'); const subs = ' ^----------!'; const expected = '-a-----c---|';
const { cold, expectObservable, expectSubscriptions } = helpers;
expectSubscriptions(e1.subscriptions) .toBe(subs);
expectObservable(e1.pipe(/without b/)) .toBe(expected);
import {TestScheduler} from 'rxjs/testing'; const testScheduler = new TestScheduler((actual, expected) => { expect(actual).toEqual(expected); });
cold('--a--b--c', { a: 'foo', b: 123, c: { x: { y: 3; }, z: false } })
-
cold()
-
hot()
-
expectObservable()
-
expectSubscriptions()
-
flush()
RunHelpers
Składnia języka Marbles
- ' ' spacja - ignorowana
- '-' jednostka ramki czasu
- '20ms', '1s', '1m' - czas pomiędzy eventami
- '|' koniec strumienia
- '#' błąd
- 'a' 'b' '1' '2' symbole eventów w strumieniu
- '()' grupowanie eventów w jednej jednostce czasu
- '^' początek subskrypcji
- '!' koniec subskrypcji
cold(' a---b 100ms (ab) 100ms c---#')
expect(/c/).toBe('----- 100ms - 100ms c---#')
Przykłady użycia w praktyce
@szafraniec_kuba


https://rxjs.dev/guide/testing/marble-testing
https://github.com/kszafraniec/rxjs-marbles-demo
Testowanie RxJS z użyciem Marbles
By Jakub Szafraniec
Testowanie RxJS z użyciem Marbles
- 251