我尝试了一切,但由于某种原因,反应状态仍然没有改变,我缺少什么或者替代方法是什么? 代码:
export const useCounter = (): UseCounterResult => {
const session = useSession();
const [list, setList] = useState<Customer[]>([]);
const [counter, setCounter] = useState(0);
const [limit, setLimit] = useState(10);
useEffect(() => {
(async () => {
const response = await getApiClient(session).listCustomers();
setList((response?.customers || []));
setCounter(response.todayCount);
setLimit(response.dailyLimit);
})();
}, [session]);
function addToList(newItem: Customer) {
setList((list) => [...newItem,...list]);
setCounter((counter) => counter + 1);
}
return {counter, limit, list, addToList};
};
我尝试过但不起作用的UT:
it.only("should add to list", async () => {
// arrange
(getApiClient as jest.Mock).mockReturnValue({
listCustomers: async () => ({
customers: [],
todayCount: 1,
dailyLimit: 5,
}),
});
// act
const { result, unmount, waitForNextUpdate, rerender } =
renderHook(useCounter);
act(() => {
result.current.addToList({
mobileNumber: "John",
receiverName: "+61456789123",
});
});
// await waitForNextUpdate();
// assert
await waitFor(() => expect(result.current.counter).toBe(2));
unmount();
});
我尝试不换行成
act
而是在其后调用 waitForNextUpdate
,仍然不起作用,result.current.counter
是 1 而不是 2
。
在您知道
addToList
内的异步 API 调用完成之前,请勿调用 useEffect
。
您可以通过断言
result.current.dailyLimit
包含从 API 返回的值来做到这一点。
在您的测试断言之后,然后继续拨打
addToList
并执行后续断言
it.only("should add to list", async () => {
// arrange
(getApiClient as jest.Mock).mockReturnValue({
listCustomers: async () => ({
customers: [],
todayCount: 1,
dailyLimit: 5,
}),
});
// act
const { result, unmount, waitForNextUpdate, rerender } =
renderHook(useCounter);
// now you know your async call has resolved
await waitFor(() => expect(result.current.dailyLimit).toEqual(5));
// call add to list - you don't need to wrap it in `act` because you have `waitFor` right after
result.current.addToList({
mobileNumber: "John",
receiverName: "+61456789123",
});
await waitFor(() => expect(result.current.counter).toBe(2));
unmount();
});