【发布时间】:2021-11-07 16:53:45
【问题描述】:
我在使用 react-native-testing-library 对组件进行单元测试时遇到问题。
我有一个这样的组件:
// components/TestComponent.js
function TestComponent() {
const [data, setData] = useState();
useEffect(() => {
clientLibrary.getData()
.then((result) => { setData(result.data); } )
.catch((err) => { //handle error here } )
}, []);
render (
<ListComponent
testID={"comp"}
data={data})
renderItem={(item) => <ListItem testID={'item'} data={item} />}
/>
);
}
我这样测试它:
// components/TestComponent.test.js
it('should render 10 list item', async () => {
const data = new Array(10).fill({}).map((v, idx) => ({
id: `v_${idx}`,
}));
const req = jest.spyOn(clientLibrary, 'getData').mockImplementation(() => {
return Promise.resolve(data);
});
const {queryByTestId, queryAllByTestId} = render(
<TestComponent />,
);
expect(await queryByTestId('comp')).toBeTruthy(); // this will pass
expect(await queryAllByTestId('item').length).toEqual(10); // this will fail with result: 0 expected: 10
}); // this failed
测试将失败/通过
Attempted to log "Warning: An update to TestComponent inside a test was not wrapped in act(...). 在 useEffect 中指向 setData。
我尝试使用act() 包装渲染,使用act() 包装断言,不模拟api 调用,将整个测试包装在act() 中,但错误不会消失。
我已经尝试查看测试库文档/git/q&a 来解决这个案例,也搜索了 stackoverflow 问题,但我仍然无法让这个测试正常工作。
谁能指出正确的方向来解决这个问题?
注意:我不是要测试实现细节。我只想测试给定一个获取结果 X,该组件将按预期呈现,即呈现 10 个列表项。
【问题讨论】:
-
您应该等待并断言使用
data在您的ListComponent中呈现的任何内容都存在 - 这将确保您的useEffect中的逻辑已经运行。 -
感谢@juliomalves 的建议。我想我应该更正我的问题中的措辞。如果我检查某些东西,测试确实通过了,但它仍然抱怨
not wrapped in act警告指向 useEffect 中的 setState,并且由于它以红色打印,我的大脑只是认为它失败了,因为这意味着我不是做正确的事,即使它通过了。如果测试通过,忽略警告是否安全?该警告并不能完全提高我对测试的信心...... -
这似乎是两个独立的问题:(1) 使用
waitFor或findBy等待异步任务解决,(2) 处理act警告。分别见how to test useEffect with act和React Native testing - act without await。
标签: react-native jestjs react-native-testing-library