React Testing Library
Links¶
Philosophy¶
- test the way your user would
- don't test internals
What RTL does¶
- what happens in a test
- render a component
- then tear it down
- do something once it's rendered
- RTL removes boilerplate
- has nice practices
- isolation of tests
Mocking non JS files¶
Jest doesn't understand
setupFilesAfterEnv['@testing-library/jest-dom/extend-expect', path.join(__dirname, 'src/test/setup')]- create React app:
setupTests.js
moduleDirectories: [path.join(__dirname, 'src')]
- unless you use Webpack aliases
Swap @testing-library/react with your own test utils¶
render¶
- queries
you don't need to use the result of render
Wrapper¶
test-utils.js
function render({ theme = "light", ...options } = {}) {
const Wrapper = ({ children }) => (
<ThemeProvider initialTheme="light">{children}</ThemeProvider>
);
return render(ui, { wrapper: Wrapper, ...options });
}
export * from "@testing-library/react";
export { render }; // use our own render
Getting DOM elements¶
screen¶
use screen instead of using queries from render
- more resilient to changes
getByRoleall the time if possible
screen.debug
Only use query* to check for non-existence
find* uses waitFor under the hood
- use it for something that might not be available right away
Mocking¶
const handleSubmit = jest.fn()
expect(handleSubmit).toHaveBeenCalledTimes(1)
Generate test data¶
faker¶
import faker from 'faker'
const buildLoginForm = (overrides) => {
username: faker.internet.userName(),
password: faker.internet.password(),
...overrides,
}
const {username, password} = buildLoginForm()
test-data-bot¶
import {build, fake} from @jackfranklin/test-data-bot
const buildLoginForm = build({
fields: {
username: fake(f => f.internet.userName()),
password: fake(f => f.internet.password()),
})
const {username, password} = buildLoginForm()
test-data-bot can create sequences
Mocking Browser APIs¶
Snapshot tesing¶
with asFragment()
const { asFragment } = render(<MyComp />)
const firstRender = asFragment()
expect(firstRender).toMatchSnapshot()
// snapshot the difference between the first and second render
userEvent.click(screen.getByText(/text/))
expect(firstRender).toMatchDiffSnapshot(asFragment())
Last update:
2023-04-24