我正在使用 react-testing-library
和 jest
来测试在设置某个 Prop 时我的 API 是否未被调用。目前,测试会立即成功,而无需完成 useEffect() 调用。如何让测试等到 useEffect
完成,这样我才能确定 API 没有被调用?
代码:
const MyComponent = ({ dontCallApi }) => {
React.useEffect(() => {
const asyncFunction = async () => {
if (dontCallApi) {
return
}
await callApi()
}
asyncFunction
}, [])
return <h1>Hi!</h1>
}
it('should not call api when dontCallApi is set', async () => {
const apiSpy = jest.spyOn(api, 'callApi')
render(<MyComponent dontCallApi />)
expect(apiSpy).not.toHaveBeenCalled()
})
最佳答案
在您的情况下,您可以监视 React.useEffect
并提供替代实现。 jest.spyOn(React, "useEffect").mockImplementation((f) => f())
所以现在您不必再关心 useEffect 的处理了。
如果您还想以下降的方式测试 useEffect,您可以在自定义 Hook 中提取逻辑并使用 testing library for hooks使用 renderHooks
函数来测试您的用例。
我会像这样测试你的组件:
import React from "react";
import { MyComponent } from "./Example";
import { render } from "@testing-library/react";
import { mocked } from "ts-jest/utils";
jest.mock("./api", () => ({
callApi: jest.fn(),
}));
import api from "./api";
const mockApi = mocked(api);
jest.spyOn(React, "useEffect").mockImplementation((f) => f());
describe("MyComponet", () => {
afterEach(() => {
jest.clearAllMocks();
});
it("should not call api when dontCallApi is set", async () => {
render(<MyComponent dontCallApi />);
expect(mockApi.callApi).toHaveBeenCalledTimes(0);
});
it("should call api when is not set", async () => {
render(<MyComponent />);
expect(mockApi.callApi).toHaveBeenCalledTimes(1);
});
});
编辑 03.07.2020
我最近发现可以在不模拟 useEffect
的情况下查询您想要的内容。您可以简单地使用 react 测试库的异步实用程序并获得以下内容:
import React from "react";
import { MyComponent } from "./TestComponent";
import { render, waitFor } from "@testing-library/react";
import { api } from "./api";
const callApiSpy = jest.spyOn(api, "callApi");
beforeEach(() => {
callApiSpy.mockImplementation(() => Promise.resolve());
});
afterEach(() => {
callApiSpy.mockClear();
});
describe("MyComponet", () => {
afterEach(() => {
jest.clearAllMocks();
});
it("should not call api when dontCallApi is set", async () => {
render(<MyComponent dontCallApi />);
await waitFor(() => expect(callApiSpy).toHaveBeenCalledTimes(0));
});
it("should call api when is not set", async () => {
render(<MyComponent />);
await waitFor(() => expect(callApiSpy).toHaveBeenCalledTimes(1));
});
});
要获得有关此的更多信息,请查看 the async utilities docs
关于reactjs - 如果在 useEffect 之后没有发生任何事情,则进行 react 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62306109/