Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing of React/Redux applications

Tags:

I'm currently investigating testing approaches for Redux/React based applications. I went through redux tutorial on testing, but still have questions:

  1. Does it make sense to test plain action creators, that just return an object with type and payload field? For me, it smells like getter/setter tests in OO applications.

  2. In a case of testing async action, should you check that corresponding actions of success and are dispatched? Again, with HTTP requests mocked, it seems as just testing mocks containers, not application behaviour.

  3. Should testing focus in reducers, since they are responsible for state transitions, means for a behaviour of connected components?

  4. Perhaps instead of testing redux guts of application, it should be tested more on a level of components? What aspects of component should be tested when? Are those tests fragile?

I'd like to hear some experience of people who use Redux/React in production and actively practicing testing.

like image 292
Alexander Beletsky Avatar asked Nov 24 '15 14:11

Alexander Beletsky


People also ask

How do I test Redux application?

Redux can be tested with any test runner, since it's just plain JavaScript. One common option is Jest, a widely used test runner that comes with Create-React-App, and is used by the Redux library repos. If you're using Vite to build your project, you may be using Vitest as your test runner.

Should you unit test React components?

Unit Testing is a testing method that tests an individual unit of software in isolation. Unit testing for React Apps means testing an individual React Component. Unit Testing is important for React Apps, as it helps in testing the individual functionality of React components.


2 Answers

I'll give a response to each question in turn, just with varying levels of detail corresponding with my experience.

tl dr: focus on application specific behavior and feature tests, let libraries worry about redux implementation details and test small reducer functions before ever being used in components.

  1. If you use an abstraction like redux-actions as I did initially using redux, then not really. If you are manually returning objects with the same properties over and over, just setup a simple test case which loops over the exposed action creators, calls them with values and checks the returned object types. Overkill for a few, but becomes a cheap sanity check for when you have many action creators. Ex:

    for (var i = 0; i < actions.length; i++) {   let action = actions[i](testData);   expect(action).to.have.property('type');   expect(action).to.have.property('payload'); } 
  2. A confusingly worded question, but in any case experience has taught me to excessively test things dealing with the network. Cover edge cases due to timeouts and throw in a few expects on the shape of the response going to reducers, and the order in which they were called.

  3. Yes it should focus on reducers. This is the most important question for it relates to one of the reasons why redux is successful. Everything is simple functions combined up into powerful and easily reasoned about functions(reducers).

    So if we had:

    const reducer = combineReducers({   a: reduceA,   b: reduceB }) 

    Then test each reducer's (reduceA and reduceB) behavior in separate test cases. You would still want to test for the returned results and their shapes but always try to break up the reducers both implementation and in testing.

  4. As before you should have small functions being used and their implementations being tested before being used in a specific component framework(here assumed react.js). If you follow the advice given in the docs

    It is advisable that only top-level components of your app (such as route handlers) are aware of Redux. Components below them should be presentational and receive all data via props.

    Then all you have to test is the top level components getting redux's dispatch passed in, and then testing if simple components call handlers like onClick, or pluck the right state out of your store but these should only have to be simple spies or assertions on the shape and value of the props, not really redux related.

like image 165
enjoylife Avatar answered Sep 20 '22 15:09

enjoylife


You can try to use redux-actions-assertions for testing of actions and action creators. It allows to write one-line readable assertions, and avoid store preparation phase.

like image 29
Dmitry Zaets Avatar answered Sep 21 '22 15:09

Dmitry Zaets