Writing Tests
Last updated
Last updated
Because most of the Redux code you write are functions, and many of them are pure, they are easy test without mocking.
We recommend as the testing engine. Note that it runs in a Node environment, so you won’t have access to DOM.
To use it together with , add this to scripts
in your package.json
:
and run npm test
to run it once, or npm run test:watch
to test on every file change.
In Redux, action creators are functions which return plain objects. When testing action creators we want to test whether the correct action creator was called and also whether the right action was returned.
can be tested like:
A reducer should return the new state after applying the action to the previous state, and that’s the behavior tested below.
can be tested like:
A nice thing about React components is that they are usually small and only rely on their props. That makes them easy to test.
can be tested like:
setState()
Then add a jsdomReact()
helper function that looks like this:
Consider the following App
component:
In a unit test, you would normally import the App
component like this:
In order to be able to test the App component itself without having to deal with the decorator, we recommend you to also export the undecorated component:
Since the default export is still the decorated component, the import statement pictured above will work as before so you won’t have to change your application code. However, you can now import the undecorated App
components in your test file like this:
And if you need both:
In the app itself, you would still import it normally:
You would only use the named export for tests.
A Note on Mixing ES6 Modules and CommonJS
Middleware functions wrap behavior of dispatch
calls in Redux, so to test this modified behavior we need to mock the behavior of the dispatch
call.
To test the components we make a setup()
helper that passes the stubbed callbacks as props and renders the component with . This lets individual tests assert on whether the callbacks were called when expected.
Shallow rendering currently . React seems to expect that, if you use setState
, DOM is available. To work around the issue, we use jsdom so React doesn’t throw the exception when DOM isn’t available. Here’s how to set it up:
Call it before running any component tests. Note this is a dirty workaround, and it can be removed once is fixed.
If you use a library like , you might be using like . This lets you inject Redux state into a regular React component.
However when you import it, you’re actually holding the wrapper component returned by connect()
, and not the App
component itself. If you want to test its interaction with Redux, this is good news: you can wrap it in a with a store created specifically for this unit test. But sometimes you want to test just the rendering of the component, without a Redux store.
If you are using ES6 in your application source, but write your tests in ES5, you should know that Babel handles the interchangeable use of ES6 import
and CommonJS require
through its capability to run two module formats side-by-side, but the behavior is . If you add a second export beside your default export, you can no longer import the default using require('./App')
. Instead you have to use require('./App').default
.
: Test utilities that ship with React.
: A plain JavaScript implementation of the DOM API. jsdom allows us to run the tests without browser.
: Shallow rendering lets you instantiate a component and get the result of its render
method just a single level deep instead of rendering components recursively to a DOM. The result of shallow rendering is a . That means it is possible to access its children, props and test if it works as expected. This also means that you changing a child component won’t affect the tests for parent component.