如何在Jest中正确地使模拟抛出错误?

2022-08-30 02:41:21

我正在使用Jest测试我的GraphQL api。

我对每个查询/突变使用单独的测试套装

我有2个测试(每个测试套装都在一个单独的测试服中),我模拟了一个用于突变的函数(即Meteor的)。callMethod

  it('should throw error if email not found', async () => {
    callMethod
      .mockReturnValue(new Error('User not found [403]'))
      .mockName('callMethod');

    const query = FORGOT_PASSWORD_MUTATION;
    const params = { email: 'user@example.com' };

    const result = await simulateQuery({ query, params });

    console.log(result);

    // test logic
    expect(callMethod).toBeCalledWith({}, 'forgotPassword', {
      email: 'user@example.com',
    });

    // test resolvers
  });

当我得到console.log(result)

{ data: { forgotPassword: true } }

这种行为不是我想要的,因为在我抛出一个错误,因此期望有一个错误对象.mockReturnValueresult

但是,在此测试之前,运行了另一个测试

 it('should throw an error if wrong credentials were provided', async () => {
    callMethod
      .mockReturnValue(new Error('cannot login'))
      .mockName('callMethod');

而且它工作正常,错误被抛出

我想问题是模拟在测试完成后不会重置。在我的我有jest.conf.jsclearMocks: true

每个测试套装都在一个单独的文件中,我在测试之前模拟函数,如下所示:

import simulateQuery from '../../../helpers/simulate-query';

import callMethod from '../../../../imports/api/users/functions/auth/helpers/call-accounts-method';

import LOGIN_WITH_PASSWORD_MUTATION from './mutations/login-with-password';

jest.mock(
  '../../../../imports/api/users/functions/auth/helpers/call-accounts-method'
);

describe('loginWithPassword mutation', function() {
...

更新

当我用一切替换时,一切都按预期进行:.mockReturnValue.mockImplementation

callMethod.mockImplementation(() => {
  throw new Error('User not found');
});

但这并不能解释为什么在另一个测试中工作正常....mockReturnValue


答案 1

更改为 :.mockReturnValue.mockImplementation

    yourMockInstance.mockImplementation(() => {
      throw new Error();
    });

如果你想断言

   test('the fetch fails with an error', () => {
     return expect(fetchData()).rejects.toMatch('error');
   });

如果这是一个承诺,你也可以拒绝.拒绝 www.jestjs.io/docs/en/asynchronous#resolves--rejects


答案 2

对于承诺,可以使用 https://jestjs.io/docs/mock-function-api#mockfnmockrejectedvaluevalue

test('async test', async () => {
  const asyncMock = jest.fn().mockRejectedValue(new Error('Async error'));

  await asyncMock(); // throws "Async error"
});

为了测试是否抛出错误,可以使用 https://eloquentcode.com/expect-a-function-to-throw-an-exception-in-jest

const func = () => {
  throw new Error('my error')
}
it('should throw an error', () => {
    expect(func).toThrow()
})