Testing React Components
Tools, Purpose & Patterns
Rajat Vijay
Frontend Engineering Manager

Certa - No Code workflow management and automation (SAAS)
TS
ReactJS

@rajatvijay

@rajatvijay
test-driven development
Tools & Purpose
- Jest
- jest-dom
- react-testing-library
- user-event
- jest-axe
Agenda
- What is Jest?
- What is jest-dom?
- Why react testing library?
- User event module
- Testing Prop updates
- Test accessibility & jest-axe
- Abstracting render function
- Integrations test cases
Jest
Jest is a Javascript test runner
- A single command to run all the tests
- Watch mode
- Assertions utilities - expect
- Coverage reporting facility
- Running tests in isolation - test.only
- Creating specifications - test.todo
jest-dom
Extending jest asserts to add more DOM specific assertions
test("renders learn react link", () => {
const root = document.createElement("div");
render(<App />, root);
const button = root.querySelector("button")!;
expect(button.disabled).toBe(true);
});
Test if a button is disabled
import "@testing-library/jest-dom";
test("renders learn react link", () => {
const root = document.createElement("div");
render(<App />, root);
const button = root.querySelector("button")!;
expect(button).toBeDisabled();
});
Test if a button is disabled
jest-dom
react-testing-library
Essentially just a set of functions to query the DOM
- Test how a user will interact with the component
- Never tests a component state or instance variables
- Tests depend on the rendered DOM, not the react component tree
- Migrate from classes to functions => Tests still work
- Migrate from HOC to hooks => Tests still work
react-testing-library
-
Render DOM from a react component
-
Query that DOM
-
Use jest assertions to test expected output
- Better debugging capabilities
- Better event management: fireEvent
user-event
fireEvent.change v/s user.type
- focus event
- keydown event
- keyup event
- blur event
Testing prop updates
test("should call the onSubmit2 after re redering", () => {
const onSubmit1 = jest.fn();
const { rerender } = render(<App onSubmit={onSubmit1} />);
const input = screen.getByLabelText("Name");
user.type(input, "Rajat");
const onSubmit2 = jest.fn();
rerender(<App onSubmit={onSubmit2} />);
const button = screen.getByRole("button");
user.click(button);
expect(onSubmit1).toBeCalledTimes(0);
expect(onSubmit2).toBeCalledTimes(1);
});
Testing accessibility
It's virtually impossible to test accessibility issues in the component.
But jest-axe can help you cover most obvious cases
Custom render function
const renderWithRedux = (
ui,
{
initialState,
store = createStore(
rootReducer,
initialState,
applyMiddleware(thunkMiddlware)
),
} = {}
) => {
return render(<Provider store={store}>{ui}</Provider>)
};
Integration tests
- Testing a parent component that renders a bunch of child components
- Test a core user flow: Signup, Login, order placing, payment, etc
- Write more integration tests as compared to unit tests
- NOTE: Never make a network call


@rajatvijay

@rajatvijay
Testing React components with Jest and React Testing Library
By rajat vijay
Testing React components with Jest and React Testing Library
What, Why & How?
- 45