我正在测试具有提交按钮的功能组件,该按钮可以对api进行异步调用。异步调用位于自定义挂钩中。根据标准测试实践,我已经模拟了该钩子,以便将调用我的模拟,而不是实际的异步api:
someComponent.test.js
jest.mock("../../../CustomHooks/user", () => ({
useUser: () => ({
error: null,
loading: false,
forgotPassword: <SOMETHING HERE>
})
}));
我知道我的forgotPassword
函数被调用,因为当我将其更改为forgotPassword: ""
时,我在测试中收到一条错误消息,指出forgotPassword不是函数。
单击我的提交按钮时调用的函数的非常简单的表示形式是:
someComponent.js
import { useUser } from "../../../CustomHooks/user"
const SomeComponent = () => {
....state and other things etc....
const { error, loading, forgotPassword } = useUser()
const submit = async () => {
await forgotPassword(emailValue);
setState(prevState => {
return {
...prevState,
content: "code"
};
});
}
}
[注意:我对异步函数await forgotPassword...
的调用被包装在我的代码的try / catch块中,但是为了清楚起见,我省略了它。
在生产中,当按下提交按钮时,将发生异步调用,然后应切换状态,从而呈现其他一些组件。我的测试旨在查看是否已经渲染了这些组件(为此,我正在使用React测试库)。
我遇到的问题是,无论我将其放在第一个代码块的占位符中,由于永远不会到达setState块,因此我的测试将始终失败。如果删除await
语句,则会命中setState块,并且由于状态已更改,所以要显示的组件在那里。但是,由于实际的调用是异步的,因此显然这在测试之外无法按预期进行。这是我尝试过的一些无效的方法:
DOESN'T WORK forgotPassword: () => { return Promise.resolve({ data: {} }); }
DOESN'T WORK forgotPassword: jest.fn(() => { return Promise.resolve(); })
DOESN'T WORK forgotPassword: jest.fn(email => { return new Promise((resolve, reject) => { if (email) { resolve(email); } else { reject("Error"); } }); }),
正如我已经说过的,如果我删除
await
语句,则状态将更改并且该组件将出现,因此测试通过。但是,出于明显的原因,这不是我想要的。
额外信息
]这是我的测试的简化版:
it("changes state/content from email to code when submit clicked", () => {
const { getByTestId, getByText, debug } = render(<RENDER THE COMPONENT>);
const submitButton = getByTestId("fpwSubmitButton");
expect(submitButton).toBeInTheDocument();
const emailInput = getByTestId("fpwEmailInput");
fireEvent.change(emailInput, {
target: { value: "[email protected]" }
});
fireEvent.click(submitButton);
debug();
THE STATEMENTS BELOW ARE WHERE IT FAILS AS THE STATE DOESN'T CHANGE WHEN AWAIT IS PRESENT
const codeInput = getByTestId("CodeInput");
expect(codeInput).toBeInTheDocument();
});
我正在测试具有提交按钮的功能组件,该按钮可以对api进行异步调用。异步调用位于自定义挂钩中。按照标准测试惯例,我嘲笑了...
尝试这样的事情