这是关于测试在
useEffect()
内具有状态更新的组件。问题是组件总是根据其默认状态进行测试。
有很多与此类似的问题,但我还没有找到任何成功的方法来测试以下内容。
MyComponent.tsx
import React from 'react'
const MyComponent = () => {
const [loaded, setLoaded] = React.useState(false)
React.useEffect(() => {
setLoaded(true)
}, [])
return (
<div>
{loaded ? (
<div data-testid="true-text"> -> line 13
true
</div> -> line 15
) : (
<div data-testid="false-text">
false
</div>
)}
</div>
)
}
export default MyComponent
MyComponent.test.tsx
/** @jest-environment jsdom */
import React from "react";
import MyComponent from "../awesome-component";
import { render, waitFor } from "@testing-library/react";
describe('MyComponent', () => {
test('should match snapshot', async () => {
const setState = jest.fn()
jest.spyOn(React, 'useState').mockImplementation(() => [false, setState]);
const { asFragment, queryByTestId } = render(<MyComponent />);
expect(asFragment()).toMatchSnapshot();
await waitFor(() => {
expect(setState).toHaveBeenNthCalledWith(1, true)
expect(queryByTestId('false-text')).toBeTruthy()
});
});
});
测试结果
› 1 snapshot updated.
-----------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------------------|---------|----------|---------|---------|-------------------
All files | 88.46 | 66.66 | 100 | 88.46 |
awesome-component.tsx | 88.46 | 66.66 | 100 | 88.46 | 13-15
-----------------------|---------|----------|---------|---------|-------------------
Snapshot Summary
› 1 snapshot updated from 1 test suite.
我需要测试
loaded === true
时渲染的组件。
从语句
expect(setState).toHaveBeenNthCalledWith(1, true)
我可以看到状态更新已经发生,但expect(queryByTestId('false-text')).toBeTruthy()
语句似乎预期正确,这意味着模板是根据false
条件渲染的。
在报道中我们可以看到
loaded === true
从未渲染过。
有人可以帮助我发展相同的测试来测试
setLoaded(true)
之后的测试吗?预先感谢。
模拟 React 组件的状态并不是一个好的做法。根据 @jonsharpe 的回答和我具有相同想法的发现,我们不应该尝试更改组件状态。
相反,我们应该做的是尝试测试组件的最终状态。