scenario
When writing unit tests for React projects using Jest, you encountered test scenarios such as clicking a button (see details) and then switching to a specified routing page (details page). Based on the idea of BDD, combined with Jest and React-testing -Library, this paper summarizes the writing ideas and problems of unit tests in this scenario.
// Component.tsx
import React from 'react'
import { useHistory } from 'react-router-dom'
const Component = () = > {
const history = useHistory()
const handleClick = (evt: React.MouseEvent) = > {
history.push(`/pageDetails? id=The ${1}`)}return (
<div>
<button onClick={handleClick}>Check the details</button>
</div>)}export default Component
Copy the code
Train of thought
Simulate the assertion after clicking a button by locating it to a button element
- The function corresponding to the click event is called
- The current route is the route after we specify the jump
pathname
- Routes carry parameters, for example
search
Is the parameter of our simulation.
// component.test.js
import React from 'react'
import { render, screen, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event'
import {createMemoryHistory} from 'history'
import Component from './component'
describe('Test Component Page'.() = > {
it('Click view Details button to jump to details page'.() = > {
render(<Component />)
const history = createMemoryHistory()
// Position the element to simulate button clicking
act(() = > {
userEvent.click(screen.getByText('Details'))})/ / assertions
expect(history.location.pathname).toBe("/pageDetails") // Assert to specify a route
expect(history.location.search).toBe("? id=1") // Assertion takes parameters
})
Copy the code
Problems encountered
- When you run a written unit test directly, clicking the button invokes the function bound to our component’s real code
handleClick
. Tests failExpected: "/pageDetails"; Received: "/"
. - The problem is that
createMemoryHistory
The default path is retrieved at execution time/
- The first option is to place the click-to-jump function in a unit test, creating a mock function and then running the test. Refer to the code below for implementation.
- Plan two can also be used
Router
The parcelComponent
The component,Router
theprops
The incominghistory
After the simulation click, assert again. referencecreateMemoryHistory
Scheme one code implementation
// component.test.js
import React from 'react'
import { render, screen, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event'
import {createMemoryHistory} from 'history'
import Component from './component'
describe('Test Component Page'.() = > {
it('Click view Details button to jump to details page'.() = > {
render(<Component />)
const history = createMemoryHistory()
const clickHandler = jest.fn(evt= > { // Create a mock click event function
evt.preventDefault()
evt.stopPropagation()
history.push('/pageDetails? id=1')
})
screen.getByText('View details').onclick = evt= > clickHandler(evt) // Bind the mock click event function to the button
act(() = > {
userEvent.click(screen.getByText('Details'))
})
expect(clickHandler).toHaveBeenCalled() // Assert that the click event is called
expect(history.location.pathname).toBe("/pageDetails") // Assert to specify a route
expect(history.location.search).toBe("? id=6") // Assertion takes parameters})})Copy the code
reference
createMemoryHistory