How to test ngrx/store dependent components in Angular 7 applications.

Piotr Rotyński
3 min readDec 12, 2018

--

Abstract: The following text will discuss different approaches to testing the angular components that use ngrx/store. Using Jasmine’s withArgs() method is available for jasmine version 3.0 users.

Testing against alternative flows

Let’s imagine ngrx/store user slice of a very simple forum like application.

Store and user component

Notice the conditional presentation of user’s registration date in this dead simple user-component. If the user is registered on the forum than their registration date is fetched on a selection from the store. Otherwise, no registration date is fetched and a static fallback text is used. The component under test is presented on code snippets below.

user.component.ts
user.component.html

The conditional logic in the template file is what we may want to test.

a) write your own store mock

One of the possible approaches to testing store dependent component would be to use self-written store mock object.

The custom mock approach

The test above is perfectly fine, but it covers only the first case (registration date is present in store). With this approach to test the second case, we need to create the component once again but this time provide another version of mock that actually returns no registration date. This will probably cause repetition of the whole beforeEach section which is not optimal.

b) use jasmine’s spy object

Another solution would be to use jasmine’s spy on the select method, provide it when the test module is being configured and then control return value from the test itself.

Using jasmine spy seems to be the more flexible solution and lets us cover both test cases without necessary hassle and code repetition.

Testing against multiple selections

Store slices and thread component

The complexity here comes from double selecting different store slices. The component under test is presented on code snippets below.

thread.component.ts
thread.component.html

a) write your own store mock

Below I present one of the possible implementations, of self-written store mock. There are of course other ways to do the same.

thread.component.spec.ts - own mock

No matter how it is implemented this approach seems to be far from perfect and for more complex components it may get tricky. The conditional logic in mock grows with each new store slice selection. Test suite built around such an approach is hardly extendable.

b) use jasmine’s spy object

Let’s see jasmine’s spies in action. Spy is created and injected on configure phase and return values are controlled from the single test.

thread.component.spec.ts -jasmine spy object

Again, using jasmine’s spy makes the code cleaner and fancier. Since the assertion strongly relies on return values it makes sense to have it in test code, not in the test suite setup phase. The main drawback here is the tight coupling between the test case and the sequence of calls in the thread component. Whenever component calls sequence changes test suite needs to follow.

c) use jasmine’s withArgs() method

thread.component.spec.ts -jasmine withArgs()

This is my personal favorite as there is no invocation dependency here. I like withArgs() that much, that I’ve created PR to add this missing cool feature to typescript typings. Describing jasmine’s spy behavior with the use of withArgs() makes it super readable as we clearly see return values in different invocations from a single test.

Note: Jasmine’s withArgs() spy method is available from version 3.0, however, it is not yet easily available for typescript users due to lack of types definitions. We will be able to use with newest jasmine and jasmine/types versions as soon as the pull request gets merged to master.

Summary:

From all methods presented above the one powered by jasmine’s spies and withArgs() seems to be the most readable and is surely my personal choice, especially in cases where component relies on multiple selections from a store.

Source code: https://github.com/piorot/ngrx-store-testing

Sign up to discover human stories that deepen your understanding of the world.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Piotr Rotyński
Piotr Rotyński

Written by Piotr Rotyński

Experienced JavaScript developer. Enthusiast of serverless on AWS, nodejs and angular. Recently fascinated with blockchain. rotynski.dev

Responses (2)

Write a response