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

Le *_*con 34 javascript meteor jestjs graphql

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

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

我有2次测试(每一个在一个单独的测试套),其中我嘲笑一个函数(即,流星的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
  });
Run Code Online (Sandbox Code Playgroud)

console.log(result)我得到

{ data: { forgotPassword: true } }
Run Code Online (Sandbox Code Playgroud)

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

然而,在此测试之前,另一个是运行

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

它工作正常,错误抛出

我想问题是测试完成后mock不会被重置.在我的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() {
...
Run Code Online (Sandbox Code Playgroud)

UPDATE

当我.mockReturnValue.mockImplementation预期的一切代替时:

callMethod.mockImplementation(() => {
  throw new Error('User not found');
});
Run Code Online (Sandbox Code Playgroud)

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

edu*_*oni 58

改变.mockReturnValue.mockImplementation:

yourMockInstance.mockImplementation(() => {
  throw new Error();
});
Run Code Online (Sandbox Code Playgroud)

  • 如果这是一个承诺,您也可以“.rejects” https://jestjs.io/docs/en/asynchronous#resolves--rejects (4认同)
  • 它抛出错误,但测试失败,因为它抛出了错误。我们如何断言? (3认同)

har*_*wla 42

对于承诺,可以使用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"
});
Run Code Online (Sandbox Code Playgroud)

要测试是否引发错误,可以使用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()
})
Run Code Online (Sandbox Code Playgroud)

  • 您还需要在您的期望中进行尝试和捕获,否则它将无法正确断言。如果我遗漏了什么,您可以改进您的答案或回复吗? (3认同)

Ang*_*Boy 8

对于 Angular + Jest:

import { throwError } from 'rxjs';

yourMockInstance.mockImplementation(() => {
  return throwError(new Error('my error message'));
});
Run Code Online (Sandbox Code Playgroud)

  • 从技术上讲,这不是纯 JS 意义上的“抛出”。您正在配置模拟以返回 RXJS 可观察对象,该对象立即发出错误通知。不过,也许人们在这里看到很方便。接受的答案肯定*会*使模拟抛出错误。在所有情况下。 (2认同)