After discussing front-end write don’t write unit tests and React Application tests: Configure Typescript, Jest, ESLint, we move on to write tests.
Selection:
- Configuration in “React Application Tests: Configure Typescript, Jest, ESLint”
- @ testing – library/react library
There are no additional assertion libraries and frameworks.
Simple rendering tests
The first step in component testing is to see if the component displays properly based on the provided properties.
Let’s say we have a simple component like myComponent.tsx:
import * as React from 'react';
export default function MyComponent() {
return <div>test</div>;
}
Copy the code
Create a myComponent.test.tsx test file next to this component (packaging tools such as Webpack do not package it) :
import * as React from 'react';
import { render } from '@testing-library/react';
import MyComponent from './MyComponent';
test('test render'.() = > {
const { getByText } = render(<MyComponent />);
expect(getByText('test')).toBeTruthy();
});
Copy the code
The test passed with flying colors. Here we use the @testing-library/react interface:
render()
Used to render the React component- by
render()
The returnedgetByText()
It’s a matching method that can find atest
The React/DOM element of the text node
I will not show the word test here as the key checkpoint to pass the test, rather than the element ID or CSS Class, because this is more appropriate for the actual requirements.
It seemed a little unreal to just go through. The test guru Kent C has a very interesting suggestion — in addition to passing your test, you should see if the test can fail if it doesn’t meet the requirements. If it doesn’t, the test is not written properly.
So let’s add a random tail to test and make it test1:
! [](simple render fail.png)
As we expected, the test failed. And @testing-library/ React kindly helped us print out the actual DOM structure rendered for subsequent debugging.
Matching method
In addition to returning getByText(), the render() function has a number of other handy matching methods:
Methods the prefix | return | Characteristics of the |
---|---|---|
getBy | Matched elements | An error is reported when there is no match or multiple matched elements |
getAllBy | Matched group of elements | An error will be reported if there is no match |
findBy | Promise and resolve are matched elements | Try to wait for this element to appear. By default, wait up to 1 second. Reject if the element expires |
findAllBy | Promise and resolve are matched elements | Same as above |
queryBy | The first matched element or null | An error is reported when multiple elements are matched |
queryAllBy | Matched group of elements or an empty array | – |
(Actually I find queryBy and queryAllBy a bit redundant…)
Note that the above is only the prefix of the method name.
- ByLabelText – Matches the text content of the form Label
- ByPlaceholderText – Placeholder text for the form elements
- ByText – Matches element text content
- ByAltText – Matches elements
alt
attribute - ByTitle – Matching element
title
attribute - ByDisplayValue – Matches the value of a form element
- ByRole – Of matching elements
role
attribute - ByTestId – Matching the element
data-testid
Property, usually an ID added for special testing requirements
The getByText() method used in the previous section is a combination of getBy and ByText.
Of course, you can also write your own.querySelectorAll(), but these methods provide some convenience.
They inherit from their @testing-library/react cousin @testing-library/dom, and are returned in the render() method for ease of use.
Test render updates
If a component can receive parameters, it is a good idea to verify that the component can update the content based on the parameters, in addition to rendering based on the attributes originally passed in.
Suppose our component myComponent.tsx now accepts a single argument:
import * as React from 'react';
export default function MyComponent({ n }: { n: number }) {
return <div>test{n}</div>;
}
Copy the code
Update myComponent.test.tsx test file:
import * as React from 'react';
import { render } from '@testing-library/react';
import MyComponent from './MyComponent';
test('test re-render'.() = > {
const { getByText, rerender } = render(<MyComponent n={1} />);
expect(getByText('test1')).toBeTruthy();
rerender(<MyComponent n={2} />);
expect(getByText('test2')).toBeTruthy();
});
Copy the code
Above, we first tried to initialize the render with n=1 as the input value, then rerender() to change the component properties to n=2 and revalidate the rendered content.
summary
We used @testing-library/react to test an unusually simple react component for rendering key content. This is not enough in practice, we need to do some other configuration to test with CSS Modules, third-party components, and complex dependencies, otherwise Jest will have all kinds of weird complaints.
Well, see you next time 👋!
Check out the other test series:
- Does the front end write unit tests? | creators camp
- The React application test: configuration Typescript, Jest, ESLint | creator training camp
- Jest test CSS Module component error how to do?
- Isolate uncontrollable factors in unit tests with Jest Mock
- Use react-testing-library to quickly test react component interactions