【问题标题】:Jest mock unnable to pick up error throw?Jest mock 无法拾取错误抛出?
【发布时间】:2020-05-22 12:12:36
【问题描述】:

我有一些调用 api 的代码。我正在测试嵌套在 try catch 中的功能,并在我抛出具有某些值的错误时检查正确的行为。

async function createDeployment(namespace, config, name) {
  try {
    await k8sDeploymentApi.createNamespacedDeployment(namespace, config, true);
    console.log('Successful deployment');
    return Promise.resolve(true);
  } catch (e) {
    console.log(JSON.stringify(e));
    if (e.response.statusCode === HTTP_CONFLICT) {
      try {
        await k8sDeploymentApi.replaceNamespacedDeployment(name, namespace, config, true);
        console.log('Successfully replaced deployment');
        return Promise.resolve(true);
      } catch (error) {
        return Promise.reject(error);
      }
    }
    return Promise.reject(e);
  }
}

我在这里模拟 api 调用节点模块

var mockListNamespacedIngress;
var mockCreateNamespacedDeployment;
var mockReplaceNamespacedDeployment;
jest.mock('@kubernetes/client-node', () => {
  mockListNamespacedIngress = jest.fn();
  mockCreateNamespacedDeployment = jest.fn();
  mockReplaceNamespacedDeployment = jest.fn();
  return {
    KubeConfig: jest.fn().mockImplementation(() => ({
      loadFromCluster: jest.fn(),
      loadFromDefault: jest.fn(),
      makeApiClient: () => ({
        listNamespacedIngress: mockListNamespacedIngress,
        createNamespacedDeployment: mockCreateNamespacedDeployment,
        replaceNamespacedDeployment: mockReplaceNamespacedDeployment,
      }),
    })),
  };
});

并在此处运行测试

    it.only('Should return a log of success if replaced deployment resolves', async () => {
      mockCreateNamespacedDeployment.mockRejectedValueOnce(() =>
        Promise.reject(new Error({ response: { statusCode: 409 } })),
      );

      mockReplaceNamespacedDeployment.mockResolvedValueOnce(true);

      // When
      await expect(createDeployment()).resolves.toEqual(true);
    });

但是,在 console.log(JSON.stringify(e)) 上,我只会得到未定义的返回。所以它似乎确实抛出了错误,但没有从 catch 中给出错误对象。这是我的完整堆栈跟踪

 ● Kubernetes deployment script tests › Kubernetes Calls › Should return a log of success if replaced deployment resolves

    expect(received).resolves.toEqual()

    Received promise rejected instead of resolved
    Rejected to value: [TypeError: Cannot read property 'statusCode' of undefined]

      143 |
      144 |       // When
    > 145 |       await expect(createDeployment()).resolves.toEqual(true);
          |             ^
      146 |     });
      147 |   });
      148 |

      at expect (node_modules/expect/build/index.js:134:15)
      at Object.it.only (src/__tests__/index.test.js:145:13)

  console.log
    Successful deployment

      at createDeployment (src/index.js:73:13)

  console.log
    undefined

      at createDeployment (src/index.js:76:13)

【问题讨论】:

    标签: javascript unit-testing mocking jestjs


    【解决方案1】:

    你可以像这样模拟一个抛出错误的异步函数

    mockCreateNamespacedDeployment.mockRejectedValueOnce(new Error({ response: { statusCode: 409 } });
    

    然后你可以期待

    await expect(createDeployment()).rejects.toThrow();
    

    顺便说一句,在您的 async 函数中,您可以替换所有的

    - Promise.resolve(xxx)
    + return xxx
    
    // and
    - Promise.reject(xxx)
    + throw xxx
    

    【讨论】:

    • 当我这样做时,我仍然得到'成功部署'的console.log,并且在catch(e)中创建的'e'变量中没有值,而不是当我正常运行代码时,当 createNamespacedDeployment 错误并带有 409 http 状态码时,它会中断。
    猜你喜欢
    • 2018-09-24
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 2017-11-19
    • 2020-12-07
    • 2019-12-23
    • 2020-09-01
    • 1970-01-01
    相关资源
    最近更新 更多