PPL 2020 — Document Builder: Testing Functional React Components with Jest

Ivana Irene Thomas
pepeel
Published in
4 min readApr 12, 2020

Writing tests for UI components can be very stressful, especially if your product is not built with the TDD paradigm and your team adopts the “if it works, it ain’t stupid” mindset. This is also what happens to our team when building Document Builder — a web app built to accommodate document template creation and document issuance.

We started off as a group of five people who all have moderate experience in writing code in React and Javascript but zero experience in writing UI tests. We never really understood the importance of writing tests for UI components. As the semester sets off and we were hit by the reality and requirements from the PPL course though, we were then forced to learn how to write UI tests and why it is important.

Choosing the testing framework

The task of choosing the right testing framework was done almost too easily. We chose Jest due to its popularity and its large community of support. It’s also readily compatible with react and the testing framework that comes with create-react-app, react-testing-framework.

Installing Dependencies

Here is the list of dependencies we install for the purpose of UI testing:

"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"jest-when": "^2.7.0",
"react-test-renderer": "^16.12.0",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",

Struggles Before The Hustles

We write all our React components in functional style so that we can utilize the React Hooks API on all of our components. All went well until we got to the testing setup part. We were using other TDD React codebase as our reference and realized that testing API for state management and functions inside React components in Jest was only available for the React.Component API, which we do not use in the project. We spent days figuring out how to test our functional components using Jest without any available APIs before we conclude that:

  • Since there is still no API for testing React Hooks, we have to find other ways to test them
  • Instead of testing what the internal functions in our React functional components do, we have to test the effect of triggering the functions instead
  • For better testability, functions that can be placed outside of UI components should be separated into new files/modules

Test if something exists in a component

A common practice for testing UI components is checking if something exists within that component and whether that something renders while the component is being rendered. For example, we want to test if the text “Forget Password” exists in our ForgetPassword Component:

What we do in this code snippet is to test if the string ‘Forget Password’ exists in the component. We can use the mount API by Enzyme to create a wrapper for our component and we can extract the string that exists in our mounted component with wrapper.text(). We can then use Jest’s API toContain to check if the string exists.

Test if a component renders a list of items correctly

One of the things we do the most on UI components is mapping props and rendering them as lists. Here’s a sample code on how to test them using the Jest:

In this code snippet, we test whether our ForgetPassword component renders list items correctly. We started by giving our mock component prop names. This component will then render them as the list of NameComponent. In the test, we check with Jest’s toHaveLength API whether the list is rendered correctly and in fact have the length 3 (matches with the length of the names props).

Test if a component prop changes when an action is triggered

In React functional component, we cannot exactly watch and test for state changes. However, we can test the side effects that happen because of state changes instead, like the change in prop values:

In this code snippet, instead of evaluating the state changes when a certain action occurs, we check for its side effects. When change occurs in the text field, we want the value of that text field to change. Instead of evaluating if the react state changes, we watch and evaluate the change in the text field’s value instead.

Mocking an API Request

One of the issues that occur a lot of times in frontend testing is the possibility and ability to mock an API request. This can be handled beautifully with jest-when library and the mockResolvedValue or mockRejectedValue API of jest. Here’s an example code snippet on how to mock API request using axios:

In this code snippet, we perform the submit action (button click) and mock the Axios request being performed after. The when and calledWithAPI allows us to mock the result of Axios request only when it is called with certain parameters.

Conclusions

Testing user interface and frontend components can be challenging at first especially without prior industry experience. Once done, however, it can help you and your team leverage the development of your product and the productivity of your team. Our experience in finding a decent way of testing also taught us that even though something does not exist and someone hasn’t built it yet, it doesn’t mean that we should ignore the problem and let it resolve itself.

Feedback is very much appreciated. Thank you for reading, I hope it was useful :)

--

--