web-dev-qa-db-fra.com

Comment se moquer de l'objet window JavaScript en utilisant Jest?

J'ai besoin de tester une fonction qui ouvre un nouvel onglet dans le navigateur

  openStatementsReport(contactIds) {
    window.open(`a_url_${contactIds}`);
  }

Je voudrais me moquer de la fonction open de la fenêtre pour pouvoir vérifier que l'URL correcte est transmise à la fonction open.

En utilisant Jest, je ne sais pas comment me moquer de la fenêtre. J'ai essayé de définir window.open avec une fonction fausse mais cette façon ne fonctionne pas. Ci-dessous le cas de test

it('correct url is called', () => {
  window.open = jest.fn();
  statementService.openStatementsReport(111);
  expect(window.open).toBeCalled();
});

mais ça me donne l'erreur

expect(jest.fn())[.not].toBeCalled()

    jest.fn() value must be a mock function or spy.
    Received:
      function: [Function anonymous]

que dois-je faire pour le cas de test? toutes suggestions ou suggestions sont appréciées

46
danny

Au lieu de window utilisez global

it('correct url is called', () => {
  global.open = jest.fn();
  statementService.openStatementsReport(111);
  expect(global.open).toBeCalled();
});

tu pourrais aussi essayer

const open = jest.fn()
Object.defineProperty(window, 'open', open);
42
Andreas Köberle

On peut aussi le définir en utilisant global dans setupTests

// setupTests.js
global.open = jest.fn()

Et appelez-le en utilisant global dans le test réel:

// yourtest.test.js
it('correct url is called', () => {
    statementService.openStatementsReport(111);
    expect(global.open).toBeCalled();
});
6
Poh Zi How

Une méthode qui a fonctionné pour moi était la suivante. Cette approche m'a permis de tester du code qui devrait fonctionner à la fois dans le navigateur et dans Node, car cela m'a permis de définir window sur undefined.

C'était avec Jest 24.8 (je crois):

let windowSpy;

beforeEach(() => {
  windowSpy = jest.spyOn(global, 'window', 'get');
});

afterEach(() => {
  windowSpy.mockRestore();
});

it('should return https://example.com', () => {
  windowSpy.mockImplementation(() => ({
    location: {
      Origin: 'https://example.com'
    }
  }));

  expect(window.location.Origin).toEqual('https://example.com');
});

it('should be undefined.', () => {
  windowSpy.mockImplementation(() => undefined);

  expect(window).toBeUndefined();
});
4
tvsbrent

Vous pouvez essayer ceci:

import * as _Window from "jsdom/lib/jsdom/browser/Window";

window.open = jest.fn().mockImplementationOnce(() => {
    return new _Window({ parsingMode: "html" });
});

it("correct url is called", () => {
    statementService.openStatementsReport(111);
    expect(window.open).toHaveBeenCalled();
});
3

Dans votre configuration jest, ajoutez setupFilesAfterEnv: ["./setupTests.js"], créez ce fichier et ajoutez le code que vous souhaitez exécuter avant les tests.

//setupTests.js
window.crypto = {
   .....
};

Réf.: https://jestjs.io/docs/fr/configuration#setupfilesafterenv-array

1
stefan

S'il est similaire au problème d'emplacement de la fenêtre à https://github.com/facebook/jest/issues/89 , vous pouvez essayer [ajusté]

delete global.window.open;
global.window = Object.create(window);
global.window.open = jest.fn();
0
serv-inc