我正在从事一个React项目,并且我正在使用JEST为我的代码编写测试。
这是我要测试的代码。
const handleSubmit = (handleSuccess, handleErrors) => {
signupAPI(user)
.then(handleSuccess)
.catch(handleErrors);
};
这是测试代码:
test('should call handleSuccess', () => {
signupAPI.mockImplementation((user) => Promise.resolve(user));
const handleSuccess = jest.fn();
const handleErrors = jest.fn();
handleSubmit(handleSuccess, handleErrors);
expect(signupAPI).toHaveBeenCalled(); // test passes
expect(handleSuccess).toHaveBeenCalled(); // test fails
});
当我运行测试时,它永远不会在承诺之后移动到"然后"部分。如何测试当时的零件内实际调用的功能?
问题是您不等待在测试中创建的承诺:
test('should call handleSuccess', async() => {
const p = Promise.resolve()
signupAPI.mockImplementation((user) => p.then(user));
const handleSuccess = jest.fn();
const handleErrors = jest.fn();
handleSubmit(handleSuccess, handleErrors);
await p
expect(signupAPI).toHaveBeenCalled(); // test passes
expect(handleSuccess).toHaveBeenCalled(); // test fails
});
如果您在 handleSubmit
中使用返回,它将起作用。尝试以下操作:
const handleSubmit = (handleSuccess, handleErrors) => {
return signupAPI(user)
.then(handleSuccess)
.catch(handleErrors);
};
和测试:
test('should call handleSuccess', () => {
signupAPI.mockImplementation((user) => Promise.resolve(user));
const handleSuccess = jest.fn();
const handleErrors = jest.fn();
handleSubmit(handleSuccess, handleErrors).then(() => {
expect(signupAPI).toHaveBeenCalled(); // test passes
expect(handleSuccess).toHaveBeenCalled(); // test fails
});
});
它应该很好!如果它不起作用,您可以尝试在测试中添加返回到handleSubmit
,例如
return handleSubmit(handleSuccess, handleErrors).then(() => {
...
});
handleSubmit
的问题是它将承诺视为荣耀的回调。无需将回调传递给then
和catch
。它不会回报诺言,所以不能束缚。
这就是可以修复的方式:
const handleSubmit = (handleSuccess, handleErrors) => {
return signupAPI(user)
.then(handleSuccess)
.catch(handleErrors);
};
和
test('should call handleSuccess', async () => {
...
handleSubmit(handleSuccess, handleErrors);
await handleSubmit(handleSuccess, handleErrors);
expect(signupAPI).toHaveBeenCalled();
expect(handleSuccess).toHaveBeenCalled();
});
这就是可以正确编写的方式:
const handleSubmit = () => signupAPI(user)