Unit Testing RxJS streams using jasmine-marbles. The demo shows how we can create a Web Component that uses NGRX/store + NGRX/effects like workflow and how we test our effect streams
2. A B O U T M E
{
"name": "Ilia Idakiev",
"experience": [
“Google Developer Expert (GDE)“,
"Developer & Co-founder @ HILLGRAND",
"Lecturer in 'Advanced JS' @ Sofia University",
"Contractor / Consultant",
"Public / Private Courses”
],
"involvedIn": [
"Angular Sofia", "SofiaJS / BeerJS",
]
}
!
3. MARBLE TESTING RXJS STREAMS
REACTIVE EXTENSIONS FOR JAVASCRIPT
▸ RxJS is a library for reactive programming using
Observables, to make it easier to compose
asynchronous or callback-based code.
5. MARBLE TESTING RXJS STREAMS
WHAT ARE MARBLE DIAGRAMS?
▸ Marble diagrams is a way of visually representing reactive (asynchronous)
data streams.
▸ In a marble diagram, the X axis (left to right) represents time.
▸ The bottom-most line always represents the output of the sequence. That is,
what your code will see if you subscribe to the operator in question.
9. MARBLE TESTING RXJS STREAMS
WHERE DO WE USE RXJS
▸ Angular (it users RxJS internally)
▸ NGRX - a framework for building reactive applications in Angular.
▸ Store - RxJS powered state management for Angular apps, inspired by
Redux.
▸ Effects - Side effect model for @ngrx/store.
12. MARBLE TESTING RXJS STREAMS
ASCII MARBLE DIAGRAMS SYNTAX
▸ “ ” - whitespace: horizontal whitespace is ignored, and can be used to help vertically align multiple
marble diagrams.
▸ “-” - frame: 1 "frame" of virtual time passing.
▸ [0-9]+[ms|s|m] - time progression: the time progression syntax lets you progress virtual time by a
specific amount. It's a number, followed by a time unit of milliseconds (ms), seconds (s) or minutes
(m).
▸ ‘|’ - complete: The successful completion of an observable.
▸ ‘#’ - error: An error terminating the observable. This is the observable producer signaling.
▸ [a-z0-9] - any alphanumeric character: Represents a value being emitted by the producer signaling.
13.
14. MARBLE TESTING RXJS STREAMS
RXJS SCHEDULERS
▸ QueueScheduler - Executes task synchronously but waits for current task to be
finished.
▸ AsapScheduler - Schedules on the micro task queue.
▸ AsyncScheduler - Schedules on the macro task queue.
▸ AnimationFrameScheduler - Relies on ‘requestAnimationFrame’.
▸ VirtualTimeScheduler - Will execute everything synchronous ordered by delay
and mainly used in testing
15. MARBLE TESTING RXJS STREAMS
JASMINE-MARBLES TEST SCHEDULER
▸ We can test our asynchronous RxJS code synchronously and deterministically
by virtualizing time using the TestScheduler
▸ At this time the TestScheduler can only be used to test code that uses timers,
like delay/debounceTime/etc (i.e. it uses AsyncScheduler with delays > 1). If
the code consumes a Promise or does scheduling with AsapScheduler/
AnimationFrameScheduler/etc it cannot be reliably tested with TestScheduler,
but instead should be tested more traditionally.
16.
17. MARBLE TESTING RXJS STREAMS
TEST SCHEDULER API
▸ testScheduler.run(callback) - callback is being executed, any operator that uses timers/AsyncScheduler (like
delay, debounceTime, etc) will **automatically** use the TestScheduler instead, so that we have "virtual time”.
▸ Helpers:
▸ hot - create hot observable
▸ cold - create cold observable
▸ expectObservable(…).toBe(…) - schedules an assertion for when the TestScheduler flushes.
▸ expectSubscriptions(…).toBe(…) - schedules an assertion for when the TestScheduler flushes but for
subscriptions on hot/cold observables.
▸ flush() - immediately starts virtual time. Not often used since run() will automatically flush for you when your
callback returns, but in some cases you may wish to flush more than once or otherwise have more control.
18. MARBLE TESTING RXJS STREAMS
ASCII MARBLE SUBSCRIPTION DIAGRAMS SYNTAX
▸ “^” - subscription point: shows the point in time at which a subscription
happen..
▸ “!” - unsubscription point: shows the point in time at which a subscription is
unsubscribed.
▸ [0-9]+[ms|s|m] - time progression: the time progression syntax lets you
progress virtual time by a specific amount. It's a number, followed by a time
unit of milliseconds (ms), seconds (s) or minutes (m).
▸ ‘-’ - time: 1 frame time passing.