Testing React
Jest Configuration
JavaScript |
---|
| // jest.config.js
module.exports = {
testEnvironment: 'jsdom',
moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json', 'node'],
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'], // add testing-library methods to expect()
transform: { '^.+\\.tsx?$': 'ts-jest'} // use ts-jest fo ts files
}
|
Jest Tests
Expect docs
JavaScript |
---|
| // .spec.js or .test.js
it("test description", () => {
// test body
expect(expected).toEqual(actual);
});
// group related tests
describe("test group name", () => {
it(/* ... */);
it(/* ... */);
});
|
Snapshots
In Component.Snapshots.js
:
JavaScript |
---|
| import React from "react";
import renderer from "react-test-renderer";
import Component from "./path/to/Component";
// import mock data if necessary
it("test description", () => {
// renders the DOM tree of the component
const tree = renderer.create(<Component funcProp={jest.fn() /* mock function */} /* component props */ />);
// save a snapshot of the component at this point in time ( in __snapshots__ folder)
// in future test it will be checked to avoid regressions
// can be updated during jest --watch pressing "u"
expect(tree).matchSnapshot();
});
|
Enzyme Configuration
JavaScript |
---|
| // testSetup.js
import { configure } from "enzyme";
import Adapter from "enzyme-adapter-react-<version>";
configure({ adapter: new Adapter() });
|
Enzyme Tests
In Component.test.js
:
JavaScript |
---|
| import React from "react";
import { shallow, mount } from "enzyme";
// eventual wrapper components (react-router, react-redux's provider, ...) for mount render
// shallow renders single component w/o children, no DOM generated
// mount renders component w/ it's children
import Component from "./path/to/Component";
// factory to setup shallow test easily
function testHelper(args) {
const defaultProps = { /* default value for props in each test */ };
const props = { ...defaultProps, ...args };
return shallow(<Component {...props} />);
}
// shallow rendering test
it("test description", () => {
const dom = testHelper(/* optional args */);
// or
const dom = shallow(<Component /* props */ />);
// check a property of expected component
// selector can be from raw JSX (name of a component)
expect(dom.find("selector").property).toBe(expected);
});
// mount rendering test
if("test description" () => {
const dom = mount(
<WrapperComponent>
<Component /* props *//>
</WrapperComponent>
);
// selector has to be HTML selector since the component is rendered completely
// possible to test child components
expect(dom.find("selector").property).toBe(expected);
});
|
Encourages to write test based on what the user sees. So components are always mounted and fully rendered.
React Testing Library Tests
In Components.test.js
:
JavaScript |
---|
| import React from "react";
import { cleanup, render } from "@testing-library/react";
import Component from "./path/to/Component";
afterEach(cleanup);
// factory to setup test easily
function testHelper(args) {
const defaultProps = { /* default value for props in each test */ };
const props = { ...defaultProps, ...args };
return render(<Component {...props} />);
}
it("test description", () => {
const { getByText } = testHelper();
// react testing library func
getByText("text"); // check if test is present in the rendered component
});
|