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
getByRole
all 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