![](/img/trans.png)
[英]How to test/mock a fetch api in a React Component using Jest?
[英]Wait for fetch() to resolve using Jest for React test?
在我的React.Component
实例的componentDidMount
中,我有一个fetch()
调用,响应调用setState
。
我可以模拟请求并使用sinon
进行响应,但我不知道 fetch 何时会解决它的承诺链。
componentDidMount() {
fetch(new Request('/blah'))
.then((response) => {
setState(() => {
return newState;
};
});
}
在我用enzyme
jest
的测试中:
it('has new behaviour from result of set state', () => {
let component = mount(<Component />);
requests.pop().respond(200);
component.update() // fetch() has not responded yet and
// thus setState has not been called yet
// so does nothing
assertNewBehaviour(); // fails
// now setState occurs after fetch() responds sometime after
});
我是否需要刷新 Promise 队列/回调队列或类似的东西? 我可以在超时的情况下重复检查 newBehaviour ,但这并不理想。
最好的答案似乎是使用容器模式并从具有分离关注点的容器类中传递 API 数据并分别测试组件。 这允许被测组件简单地将 API 数据作为 props 并使其更易于测试。
由于您没有进行任何真正的 api 调用或其他耗时的操作,因此异步操作将在可预见的短时间内解决。
因此,您只需稍等片刻即可。
it('has new behaviour from result of set state', (done) => {
let component = mount(<Component />);
requests.pop().respond(200);
setTimeout(() => {
try {
component.update();
assertNewBehaviour();
done();
} catch (error) {
done(error);
}
}, 1000);
});
react 测试库有一个waitFor
函数,非常适合这种情况。
我将举一个带有钩子和函数的例子,因为那是当前的反应模式。 假设您有一个类似于此的组件:
export function TestingComponent(props: Props) {
const [banners, setBanners] = useState<MyType>([]);
React.useEffect(() => {
const response = await get("/...");
setBanners(response.banners);
}, []);
return (
{banners.length > 0 ? <Component> : </NoComponent>}
);
}
现在您可以编写这样的测试来确保在设置横幅时渲染Component
test("when the banner matches the url it renders", async () => {
const {container} = render(<TestingComponent />);
await waitFor(() => {expect(...).toBe(...)});
});
waitFor
将等待函数中的条件满足,然后再继续。 如果在 X 时间内不满足条件,则会有超时导致测试失败。 查看反应测试库文档以获取更多信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.