Wie kann man einen Scheinwurf in Jest richtig machen?

75

Ich teste meine GraphQL-API mit Jest.

Ich verwende für jede Abfrage / Mutation einen separaten Testanzug

Ich habe 2 Tests (jeder in einem separaten Testanzug), bei denen ich eine Funktion (nämlich Meteor callMethod) verspotte , die bei Mutationen verwendet wird.

  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: '[email protected]' };

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

    console.log(result);

    // test logic
    expect(callMethod).toBeCalledWith({}, 'forgotPassword', {
      email: '[email protected]',
    });

    // test resolvers
  });

Wenn console.log(result)ich bekomme

{ data: { forgotPassword: true } }

Dieses Verhalten ist nicht das, was ich will , weil in .mockReturnValueich einen Fehler aus , und daher erwarten , resultein Fehlerobjekt haben ,

Vor diesem Test wird jedoch ein anderer ausgeführt

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

Und es funktioniert gut, der Fehler wird geworfen

Ich denke, das Problem ist, dass Mock nach Abschluss des Tests nicht zurückgesetzt wird. In meinem jest.conf.jshabe ich clearMocks: true

Jeder Testanzug befindet sich in einer separaten Datei, und ich verspotte Funktionen vor Tests wie diesen:

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() {
...

AKTUALISIEREN

Als ich .mockReturnValuemit .mockImplementationallem ersetzte, hat alles wie erwartet geklappt:

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

Aber das erklärt nicht, warum in einem anderen Test gut .mockReturnValuefunktioniert ...

Le garcon
quelle
Es sieht aus wie Ihre Mock wird Rückkehr ein Fehler Objekt, nicht werfen es. Ohne Ihren Code zu sehen, den Sie testen, kann ich nur die Erfahrungen teilen, die ich gemacht habe. Ich habe vergessen, eine in meiner Mutation aufgerufene Funktion zu verspotten, wodurch ein Fehler unbeabsichtigt ausgelöst wurde. Vielleicht passiert etwas Ähnliches für Sie?
Rhuarc13

Antworten:

3

Für Angular + Jest:

import { throwError } from 'rxjs';

yourMockInstance.mockImplementation(() => {
  return throwError(new Error('my error message'));
});
AngularBoy
quelle
1
Technisch gesehen ist dies kein throwreiner JS-Sinne. Sie konfigurieren den Mock so, dass er ein beobachtbares RXJS-Objekt zurückgibt, das sofort eine Fehlerbenachrichtigung ausgibt. Trotzdem vielleicht praktisch für Leute, die hier sehen können. Die akzeptierte Antwort sicherlich wird ein Mock macht einen Fehler aus. Auf alle Fälle.
Zach Lysobey