You may choose a testing stack as you please, with a few exceptions they are all very similar in their functioanlity and APIs. For the purposees of this document we will be using Ava, Enzyme, JSDom and Sinon.
-
Ava a lightning quick test runner and assertion library.
-
Enzyme a react component test utility allowing us to access the DOM with jQuery like syntax.
-
JSDom headless javascript browser for DOM.
-
Sinon for mocking out any function behaviour.
Seting up these libraries is out of scope with this document, please refer to the relevant docs and the testing redux-form example repository.
When testing React components it's important to understand what actually needs test coverage. We only want to test the behaviour of our <CreateUser />
form component, not the underlying implimentations involved in that behaviour. What does that mean? Good question!
For example in our component we pass in a property called createUser
, a function that sends the data back to our server. This is called within the submit()
function of the component that is inturn called via handleSubmit()
property passed in by redux-form
.
Both the createUser
and handleSubmit
functions can be considered external dependancies. In the case of handleSubmit
it has test coverage within the redux-form
library itself. Also you should have your own tests giving coverage to the createUser
API functionality. Therefore we DO NOT write test for these. Another example of this concept: If we were using a react-boostrap
button as our submit button, we DO NOT want to test how this button works, its an external dependancy with its own test.
Let's break down the behaviour of our form:
- It renders a single
<form />
element - It renders the correct form
<input />
elements - It renders a submit
<button />
- The form is submitted when the button is clicked
- When the form is submitted handle submit is called with our components submit function.
Firstly as we are only testing the behaviour of our <CreateUser />
component and not the redux-form
library, we want to export a non-connected / decorated version of our component to test. You will notice at the bottom of the component we export the redux-form
conntected version as the default export. This makes it easy to use within our application. Also created a named export, that exports the isolated - component only - version. If this is confusing please readup on ES6 module exports / imports before proceeding.
hello, you are rendering undefined
<ProfileForm />
component instead of<CreateUser />
you've imported on line 6.