【问题标题】:How to test the then part after promise in jest如何在开玩笑的承诺之后测试 then 部分
【发布时间】:2019-07-21 03:07:34
【问题描述】:

我正在开发一个 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
});

当我运行测试时,它永远不会移动到 promise 之后的“then”部分。如何测试 then 部分中的函数是否实际被调用?

【问题讨论】:

    标签: reactjs testing jestjs


    【解决方案1】:

    问题是你没有等待你在测试中创建的承诺:

    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
    });
    

    【讨论】:

      【解决方案2】:

      handleSubmit 的问题在于它将 Promise 视为美化的回调。无需将回调传递给thencatch。它不返回承诺,因此不能被链接。

      可以这样解决:

      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)
      

      【讨论】:

      • 这个解决方案在某些特殊情况下并不总是适合我
      【解决方案3】:

      如果您在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(() => {
        ...
      }); 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-10
        • 2018-12-10
        • 2022-06-10
        • 2018-11-19
        • 1970-01-01
        • 1970-01-01
        • 2022-06-29
        • 1970-01-01
        相关资源
        最近更新 更多