Testing side effects using redux saga

Testing side effects using redux saga

Posted by Martin Bielik | September 9, 2016 | javascript, react, redux, testing

In this post I’ll try to show you how convenient it is to test side effects using redux saga. To read this post you should know something about generators and redux-saga library. Here are some great articles about this topic:

To test my code I use mocha and chai  libraries. I will use my Api module which exports functions for data fetching (using promises and callbacks, the implementation is not important). In sagasall side effects should be created using helper functions from redux-saga/effects package. I will omit importing all those modules in my examples, this is how imports look like:

Simple good case

Let’s start with simple saga which fetches articles from the server using promise API:

To test this code you need to create generator and iterate it manually.  Value of each iteration represents side effect itself and you can easily assert it.The result of asynchronous fetch action can be passed as an argument of next method. There is no need for mocking. Convenient, isn’t it?:

Error testing

In case of error, the saga above ends in catch block and calls FETCH_ARTICLE_FAILED action. To simulate error in test we can use throw method of generator. The final test looks like this:

Callbacks

If you have to use error first callback functions instead of promises, redux saga provides helper function for it – cps . It can be simply used instead of call function. Let’s suppose I have callback API for adding comments. This is how my saga looks like:

Testing of callback API it is as simple as testing promises (and any other side effects):

Parallel Tasks

One of the features of the saga is that you can run multiple tasks in parallel and wait for the final result. For example here is saga which preloads articles with given ids. Fetching of articles is done concurrently:

It is not a big deal to test code like this in sagas. Parallel calls can be asserted the same way it has been called – in array:

Task cancelation

In certain cases you need to test if task has been cancelled. Consider login/logout action. When login is in progress and the user clicks logout button, login should be cancelled. Saga provides mechanism to cancel effects using cancel helper function:

To test task cancellation it is the same as with other side effects. The only thing you need is to create Task  object represinting the task which is returned from non-blocking fork effect. There is helper function for it – createMockTask:

Root saga

To put it all together you can create root saga which watches for incomming actions and starts login flow:

The test is pretty strightforward:

Conclusion

Redux saga adds structure to your code and separate side effect logic from the rest of the application. One of the greatest benefit is the code testability. You don’t need any complex mocking and injecting dependencies everywhere. The tests of side effect are simple, easy to write and read.

Add a comment

*Please complete all fields correctly

Related Blogs

Posted by miklik | 08 September 2017
Why do I need one? Every programmer has its own coding style. It is polite to honour the style of the file I am editing but when I am starting…
Posted by miklik | 24 February 2017
Recently we were invited to help others to resolve compatibility issues between IOS and Android. They have started with React Native but have developed their application only for Android. And…
Posted by miklik | 19 December 2016
What do you want for christmas? We wanted a color picker for React Native but we could not find any. Therefore we made one for you. You can find it…