react code javascript unit-testing dependencies jestjs babel-jest

javascript - code - jest react



Mocking globals en broma (2)

¿Hay alguna forma en Jest para simular objetos globales, como el navigator o la Image *? Me he rendido bastante a esto y lo he dejado en una serie de métodos de utilidad simulables. Por ejemplo:

// Utils.js export isOnline() { return navigator.onLine; }

Probar esta pequeña función es simple, pero crufty y no determinista en absoluto. Puedo obtener el 75% del camino, pero esto es lo más lejos que puedo llegar:

// Utils.test.js it(''knows if it is online'', () => { const { isOnline } = require(''path/to/Utils''); expect(() => isOnline()).not.toThrow(); expect(typeof isOnline()).toBe(''boolean''); });

Por otro lado, si estoy de acuerdo con este direccionamiento, ahora puedo acceder al navigator través de estas utilidades:

// Foo.js import { isOnline } from ''./Utils''; export default class Foo { doSomethingOnline() { if (!isOnline()) throw new Error(''Not online''); /* More implementation */ } }

... y prueba deterministicamente asi ...

// Foo.test.js it(''throws when offline'', () => { const Utils = require(''../services/Utils''); Utils.isOnline = jest.fn(() => isOnline); const Foo = require(''../path/to/Foo'').default; let foo = new Foo(); // User is offline -- should fail let isOnline = false; expect(() => foo.doSomethingOnline()).toThrow(); // User is online -- should be okay isOnline = true; expect(() => foo.doSomethingOnline()).not.toThrow(); });

De todos los marcos de prueba que he usado, Jest se siente como la solución más completa, pero cada vez que escribo un código extraño para que sea comprobable, siento que mis herramientas de prueba me están fallando.

¿Es esta la única solución o debo agregar Rewire?

* No sonríes Image es fantástica para hacer ping a un recurso de red remota.


Como cada prueba ejecuta su propio entorno, puede simularse globalmente simplemente sobrescribiéndolos. El espacio de nombres global puede acceder a todas las vars global .

global.navigator = { onLine: true }

La sobrescritura solo tiene efectos en su prueba actual y no afectará a otros. Esta también es una buena manera de manejar Math.random o Date.now

Tenga en cuenta que, a través de algunos cambios en jsdom, es posible que tenga que simularse de manera global:

Object.defineProperty(globalObject, key, { value, writable: true });


Es posible que Jest haya cambiado desde que se escribió la respuesta aceptada, pero Jest no parece restablecer su global después de la prueba. Por favor, consulte los testcases adjuntos.

https://repl.it/repls/DecentPlushDeals

Por lo que sé, la única forma de evitar esto es con afterEach() o afterAll() para limpiar sus asignaciones a global .