Unit testing tools in React applications
February 28, 2022 (2 years ago)
In JS applications, many types of testing provide business value and security for businesses. These include:
- Unit tests, which test business logic of small pieces of code
- Integration tests, which test how microservices & services function
- End-to-end tests (e2e)
Each of these tests are important, but if you are just starting testing now, then unit tests are a great place to start, especially if you don't have a lot of experience writing tests.
You should use Jest to write your tests, as most testing packages use it. Jest combines the best of Istanbul, Jasmine, and all of the test and coverage reporters into a fantastic interface.
Here's a nice example of a Jest unit test from Smashing Magazine (https://www.smashingmagazine.com/2020/06/practical-guide-testing-react-applications-jest/):
describe("Testing Accounts", () => {
it("accepts user account props", () => {
const wrapper = render(<Account user={user} />);
expect(wrapper.props().user).toEqual(user);
});
it("contains users account email", () => {
const wrapper = render(<Account user={user} />);
const value = wrapper.find("p").text();
expect(value).toEqual("[email protected]");
});
});
ts-jest
should be used wherever possible. Avoid rewire
like the plague. And here's some more Jest docs with React: https://jestjs.io/docs/tutorial-react.
Metrics
A good early metric for testing is test coverage. jest --coverage
will output your coverage, and show you your tested and untested files.
Your CI tool should have a way of uploading your coverage to pull requests so the team can have a good idea of how well changes are tested before they are merged.
Good testing packages
React, being such a popular framework, has many nice unit testing helpers which make your life easier.
react-testing-library
The industry standard for testing React. Here's a great example from Kent C. Dodds: https://codesandbox.io/s/o27kw5oly?file=/src/__tests__/hooktest.js
@testing-library/react-hooks
This library allows you to test the hooks in your application. Here's a great example: https://github.com/testing-library/react-hooks-testing-library#usecountertestjs
jest-dom
Allows you to unit test your HTML DOM elements from rendered components. Pretty handy: https://github.com/testing-library/jest-dom#examples.
Difficulties
The hardest thing in my experience about writing unit tests is mocking. When you are testing a small part of an app, you need to abstract at least some of the services e.g. database writers, etc.
Jest is a fantastic tool for mocking -- it doesn't need dependency injection like C# testers; it can rewrite the module imports themselves! How cool is that!
Check out https://jestjs.io/docs/mock-functions for documentation about mocking.
Usually, I mock all my own services including express. If any of you have good mocks for these services, let me know!
It is good to avoid the urge to over-abstract when writing tests (hard, I know). Copy and paste is your friend in unit tests.
Also, if you're using typescript, remember to use jest.mocked()
for typings. You need to have the very latest @types/jest
and jest
for this to work, this has just been merged: https://github.com/facebook/jest/pull/12089.
Final words
If you are on the fence about unit testing, then I strongly suggest you try it out. Many good developers, even now, resist testing. You can write great products without testing, just like you can write great applications in C instead of Rust.
However, as your team grows, and you have more features and code changes coming through, unit tests are a good way to ensure that your code is well thought out, and unexpected cases are covered. The more you can cover your testing pyramid the better.