Se moquant globals dans la Plaisanterie
Est-il de toute façon à la Blague pour se moquer des objets globaux, tels que navigator
, ou Image
*? J'ai à peu près renoncé à ce, et a laissé une série de mockable les méthodes de l'utilitaire. Par exemple:
//Utils.js
export isOnline() {
return navigator.onLine;
}
Tester cette petite fonction est simple, mais crufty et non déterministe à tous. Je peux obtenir 75% du chemin, mais c'est à peu près aussi loin que je peux aller:
//Utils.test.js
it('knows if it is online', () => {
const { isOnline } = require('path/to/Utils');
expect(() => isOnline()).not.toThrow();
expect(typeof isOnline()).toBe('boolean');
});
D'autre part, si je suis d'accord avec cette indirection, je peux maintenant accéder à navigator
par l'intermédiaire de ces utilitaires:
//Foo.js
import { isOnline } from './Utils';
export default class Foo {
doSomethingOnline() {
if (!isOnline()) throw new Error('Not online');
/* More implementation */
}
}
...et de façon déterministe test comme ça...
//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 toutes les infrastructures de test que j'ai utilisé, la Blague se sent comme la solution la plus complète, mais chaque fois que j'écris maladroit code juste pour rendre testable, je sens que mes outils de test sont de me laisser descendre.
Est-ce la seule solution ou dois-je besoin d'ajouter Rewire?
*Ne pas sourire en coin. Image
est fantastique pour une requête ping à une ressource réseau à distance.
Vous devez vous connecter pour publier un commentaire.
Comme chaque essai de son propre environnement, vous pouvez vous moquer globals par juste de les remplacer. Toutes les variables globales peuvent être accessibles par le
global
d'espace de nom.Le remplacement a seulement des effets dans votre test en cours et ne pas affecter d'autres personnes. Ceci est également un bon moyen de traiter
Math.random
ouDate.now
Remarque, que par le biais de quelques changements dans jsdom il pourrait être possible que vous ayez à se moquer globals comme ceci:
global
être le même quewindow
dans le navigateur?window
est également présent dansglobal
. C'est pourquoi je n'utilise pasglobal.navigator.onLine
parce que je ne suis pas sûr qu'il y a unnavigator
objet dansglobal
.performance
, que je n'avais jamais vu avant, donc j'ai fait:global.performance = { now: () => {} };
Plaisanterie peut avoir changé depuis que l'on a accepté la réponse a été écrite, mais la Plaisanterie n'apparaît pas à réinitialiser votre mondial après les tests. Veuillez voir le cas de tests ci-joint.
https://repl.it/repls/DecentPlushDeals
Autant que je sache, la seule façon de contourner cela est avec un
afterEach()
ouafterAll()
pour nettoyer vos missions àglobal
.jest.clearAllMocks();
dansafterEach()
m'a aidéSi quelqu'un a besoin de se moquer d'un mondiale avec propriétés statiques alors mon exemple devriez aider: