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
  • byrender()The returnedgetByText()It’s a matching method that can find atestThe 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 elementsaltattribute
  • ByTitle – Matching elementtitleattribute
  • ByDisplayValue – Matches the value of a form element
  • ByRole – Of matching elementsroleattribute
  • ByTestId – Matching the elementdata-testidProperty, 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