被迫重新查询元素以触发点击处理程序
Forced to re-query element in order to fire click handler
我有一个测试,我断言我的 API 请求提供了正确的参数。我正在使用 MSW 来模拟 api,并且我为请求处理程序提供了一个间谍:
test("supplies order direction descending if header button is clicked twice", async () => {
const mockHandler = jest.fn(handler);
server.use(rest.get(`${config.apiHost}/targets`, mockHandler));
// First request to /targets happens on render
render(<Route>{(props) => <TargetList history={props.history} />}</Route>);
const button = await screen.findByRole("button", { name: "Port" });
// Second request to /targets happens on button click
userEvent.click(button);
await waitFor(() => {
expect(mockHandler).toHaveBeenCalledTimes(2);
});
// Third request to /targets SHOULD happen here but doesn't
userEvent.click(button);
await waitFor(() => {
expect(mockHandler).toHaveBeenCalledTimes(3);
const lastCall = mockHandler.mock.calls[2];
const requestArg = lastCall[0];
expect(requestArg.url.searchParams.get("orderby")).toBe("port");
expect(requestArg.url.searchParams.get("direction")).toBe("descending");
});
});
上面的代码不起作用,因为在按钮上第二次触发点击事件似乎什么也没做。但是,如果我重新查询按钮,那么我可以成功触发处理程序:
test("supplies order direction descending if header button is clicked twice", async () => {
...
const button = await screen.findByRole("button", { name: "Port" });
// Second request to /targets happens on b utton click
userEvent.click(button);
await waitFor(() => {
expect(mockHandler).toHaveBeenCalledTimes(2);
});
// Third request to /targets now works!
const button2 = await screen.findByRole("button", { name: "Port" });
userEvent.click(button2);
await waitFor(() => {
expect(mockHandler).toHaveBeenCalledTimes(3); // SUCCESS!
...
});
});
为什么我必须重新查询相同的元素?我做错了什么吗?
我没有完整的源代码,但我假设你正在对你的点击事件处理程序做一些事情,这将强制反应再次呈现,在这种情况下,旧元素将不再出现在 DOM 上,并且因此不会调用单击事件处理程序。
P.S:您可以使用 React 生命周期挂钩来确定组件是否为 re-rendered。
我有一个测试,我断言我的 API 请求提供了正确的参数。我正在使用 MSW 来模拟 api,并且我为请求处理程序提供了一个间谍:
test("supplies order direction descending if header button is clicked twice", async () => {
const mockHandler = jest.fn(handler);
server.use(rest.get(`${config.apiHost}/targets`, mockHandler));
// First request to /targets happens on render
render(<Route>{(props) => <TargetList history={props.history} />}</Route>);
const button = await screen.findByRole("button", { name: "Port" });
// Second request to /targets happens on button click
userEvent.click(button);
await waitFor(() => {
expect(mockHandler).toHaveBeenCalledTimes(2);
});
// Third request to /targets SHOULD happen here but doesn't
userEvent.click(button);
await waitFor(() => {
expect(mockHandler).toHaveBeenCalledTimes(3);
const lastCall = mockHandler.mock.calls[2];
const requestArg = lastCall[0];
expect(requestArg.url.searchParams.get("orderby")).toBe("port");
expect(requestArg.url.searchParams.get("direction")).toBe("descending");
});
});
上面的代码不起作用,因为在按钮上第二次触发点击事件似乎什么也没做。但是,如果我重新查询按钮,那么我可以成功触发处理程序:
test("supplies order direction descending if header button is clicked twice", async () => {
...
const button = await screen.findByRole("button", { name: "Port" });
// Second request to /targets happens on b utton click
userEvent.click(button);
await waitFor(() => {
expect(mockHandler).toHaveBeenCalledTimes(2);
});
// Third request to /targets now works!
const button2 = await screen.findByRole("button", { name: "Port" });
userEvent.click(button2);
await waitFor(() => {
expect(mockHandler).toHaveBeenCalledTimes(3); // SUCCESS!
...
});
});
为什么我必须重新查询相同的元素?我做错了什么吗?
我没有完整的源代码,但我假设你正在对你的点击事件处理程序做一些事情,这将强制反应再次呈现,在这种情况下,旧元素将不再出现在 DOM 上,并且因此不会调用单击事件处理程序。
P.S:您可以使用 React 生命周期挂钩来确定组件是否为 re-rendered。