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


80

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

我为每个查询/突变使用单独的测试服

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

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

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

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

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

它工作正常,引发了错误

我想问题是测试完成后模拟不会重置。在我jest.conf.js我有 clearMocks: 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效果很好...


看起来您的模拟正在返回错误对象,而不是抛出。在没有看到您要测试的代码的情况下,我只能分享我的经验。我忘了模拟我的突变中调用的函数,该函数导致意外抛出错误。也许您正在发生类似的事情?
Rhuarc13

Answers:



3

对于Angular + Jest:

import { throwError } from 'rxjs';

yourMockInstance.mockImplementation(() => {
  return throwError(new Error('my error message'));
});

1
从技术上讲,这并不是throw纯粹的JS。您正在配置模拟以返回RXJS可观察对象,该对象立即发出错误通知。尽管如此,对于人们来说还是很方便的。接受的答案肯定做一个模拟抛出一个错误。在所有情况下。
Zach Lysobey
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.