gpt4 book ai didi

reactjs - 使用react-testing-library进行测试时可以手动触发状态更改吗?

转载 作者:行者123 更新时间:2023-12-03 13:35:00 26 4
gpt4 key购买 nike

我仍在将我的 enzyme 测试转移到react-testing-library,并且我有一个相当常见的场景,当组件安装时,它会启动 Ajax 请求以获取一些数据。在获取开始之前,它会设置一些状态值来指示它正在加载,这反过来会呈现一个旋转器。完成后,状态将使用这两个数据进行更新,并且“loadingState”将在适当的情况下设置为“Completed”或“Failed”。

import React, { useEffect, useState } from "react";
import { SwapSpinner } from "react-spinners-kit";
import styled from "styled-components";
import * as R from "ramda";

import { getPeople } from "./getPeople";

const FlexCenter = styled.div`
height: 250px;
display: flex;
justify-content: center;
align-items: center;
`;

const loadingStates = {
notStarted: "notStarted",
isLoading: "isLoading",
success: "success",
failure: "failure"
};

function App() {
const [people, setPeople] = useState([]);
const [isLoading, setLoading] = useState(loadingStates.notStarted);

useEffect(() => {
setLoading(loadingStates.isLoading);
getPeople()
.then(({ results }) => {
setPeople(results);
setLoading(loadingStates.success);
})
.catch(error => {
setLoading(loadingStates.failure);
});
}, []);

return (
<div>
{R.cond([
[
R.equals(loadingStates.isLoading),
() => (
<FlexCenter data-testid="spinner">
<SwapSpinner />
</FlexCenter>
)
],
[
R.equals(loadingStates.success),
() => (
<ul data-testid="people-list">
{people.map(({ name }) => (
<li key={name}>{name}</li>
))}
</ul>
)
],
[R.equals(loadingStates.failure), <div>An error occured</div>]
])(isLoading)}
</div>
);
}

export default App;

使用 Enzyme,我可以手动将状态设置为任何一个 loadingStates 键,并断言渲染条件会渲染适当的更改。

有没有办法可以在 RTL 中做到这一点?

最佳答案

使用 RTL 无法做到这一点。您不应该与组件的内部进行交互。

这大致就是我测试您的组件的方式:

import { getPeople } from "./getPeople";
jest.mock('./getPeople')

test('skeleton of a test', async () => {
const people = [/* Put some mock people in here */]
getPeople.mockResolvedValueOnce({ results: people })
render(<App />)

expect(/* Somehow get the loading spinner */).toBeInTheDocument()

await wait(() => expect(/* Here you check that the people is on the page */).toBeInTheDocument())

// We also check that the API gets called
expect(getPeople).toHaveBeenCalledOnce()
expect(getPeople).toHaveBeenCalledWith()
})

如您所见,我没有检查 App 的内部状态。相反,我检查是否显示了加载旋转器,之后人员出现在屏幕上并且 API 被调用。

此测试更可靠,因为您测试的是用户会看到的内容,而不是实现细节。

关于reactjs - 使用react-testing-library进行测试时可以手动触发状态更改吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54837512/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com