我无法通过以下测试:
import { useEffect, useState } from "react";
export function useComponentResources(required) {
const [componentResources, setComponentResources] = useState(null);
useEffect(() => {
if (required) {
// api call
setTimeout(() => setComponentResources({}), 100);
}
}, [required]);
return componentResources;
}
import { renderHook } from "@testing-library/react-hooks";
import { useComponentResources } from "./component-resources.hook";
describe("component-resources.hook", () => {
it("fetches resources when required", () => {
//act
const { result } = renderHook(() => useComponentResources(true));
//assert
expect(result.current).toEqual({});
});
});
它不断失败:
expect(received).toEqual(expected)
Expected value to equal:
{}
Received:
null
Difference:
Comparing two different types of values. Expected object but received null.
7 | const { result } = renderHook(() => useComponentResources(true));
9 | //assert
> 10 | expect(result.current).toEqual({});
11 | });
12 | });
我已经在codeandbox中创建了一个repro案例:
答案 0 :(得分:0)
renderHook
不会等待您的setTimeout
被解雇;它不知道您的组件有什么“副作用”。因此,当您的expect()
运行时,当前值仍是其默认值-null
。
我们可以使用waitForNextUpdate
返回的对象上的renderHook
来强制测试等待钩子再次更新。 waitForNextUpdate
是一个函数,它返回一个承诺,该承诺将在钩子再次更新后(例如setTimeout触发时)解决。
import { renderHook } from "@testing-library/react-hooks";
import { useComponentResources } from "./component-resources.hook";
describe("component-resources.hook", () => {
it("fetches resources when required", async () => {
const { result, waitForNextUpdate } = renderHook(() => useComponentResources(true));
await waitForNextUpdate();
expect(result.current).toEqual({});
});
});