javascript - modules - ¿Cómo puedo simular una importación de módulo ES6 usando Jest?
import javascript (6)
Estoy empezando a pensar que esto no es posible, pero quiero preguntar de todos modos.
Quiero probar que uno de mis módulos ES6 llama a otro módulo ES6 de una manera particular. Con Jasmine esto es muy fácil:
El código de la aplicación:
// myModule.js
import dependency from ''./dependency'';
export default (x) => {
dependency.doSomething(x * 2);
}
Y el código de prueba:
//myModule-test.js
import myModule from ''../myModule'';
import dependency from ''../dependency'';
describe(''myModule'', () => {
it(''calls the dependency with double the input'', () => {
spyOn(dependency, ''doSomething'');
myModule(2);
expect(dependency.doSomething).toHaveBeenCalledWith(4);
});
});
¿Cuál es el equivalente con Jest? Siento que esto es algo muy simple que quiero hacer, pero me he estado arrancando el pelo tratando de resolverlo.
Lo más cerca que he estado es reemplazando las
import
s con
require
s, y moviéndolas dentro de las pruebas / funciones.
Ninguno de los cuales son cosas que quiero hacer.
// myModule.js
export default (x) => {
const dependency = require(''./dependency''); // yuck
dependency.doSomething(x * 2);
}
//myModule-test.js
describe(''myModule'', () => {
it(''calls the dependency with double the input'', () => {
jest.mock(''../dependency'');
myModule(2);
const dependency = require(''../dependency''); // also yuck
expect(dependency.doSomething).toBeCalledWith(4);
});
});
Para obtener puntos de bonificación, me encantaría hacer que todo funcione cuando la función dentro de
dependency.js
es una exportación predeterminada.
Sin embargo, sé que espiar las exportaciones predeterminadas no funciona en Jasmine (o al menos nunca podría hacerlo funcionar), por lo que tampoco tengo la esperanza de que sea posible en Jest.
Añadiendo más a la respuesta de Andreas. Tuve el mismo problema con el código ES6 pero no quise mutar las importaciones. Eso parecía hacky. Entonces hice esto
import myModule from ''../myModule'';
import dependency from ''../dependency'';
jest.mock(''../dependency'');
describe(''myModule'', () => {
it(''calls the dependency with double the input'', () => {
myModule(2);
});
});
Y agregó dependency.js en la carpeta "__ mocks __" paralela a dependency.js. Esto funcionó para mí. Además, esto me dio la opción de devolver datos adecuados de la implementación simulada. Asegúrese de dar la ruta correcta al módulo que desea simular.
He podido resolver esto usando un truco que involucra
import *
.
¡Incluso funciona para exportaciones con nombre y predeterminadas!
Para una exportación con nombre:
// dependency.js
export const doSomething = (y) => console.log(y)
// myModule.js
import { doSomething } from ''./dependency'';
export default (x) => {
doSomething(x * 2);
}
// myModule-test.js
import myModule from ''../myModule'';
import * as dependency from ''../dependency'';
describe(''myModule'', () => {
it(''calls the dependency with double the input'', () => {
dependency.doSomething = jest.fn(); // Mutate the named export
myModule(2);
expect(dependency.doSomething).toBeCalledWith(4);
});
});
O para una exportación predeterminada:
// dependency.js
export default (y) => console.log(y)
// myModule.js
import dependency from ''./dependency''; // Note lack of curlies
export default (x) => {
dependency(x * 2);
}
// myModule-test.js
import myModule from ''../myModule'';
import * as dependency from ''../dependency'';
describe(''myModule'', () => {
it(''calls the dependency with double the input'', () => {
dependency.default = jest.fn(); // Mutate the default export
myModule(2);
expect(dependency.default).toBeCalledWith(4); // Assert against the default
});
});
Como Mihai Damian señaló con razón a continuación, esto está mutando el objeto de
dependency
del módulo, por lo que se ''filtrará'' a otras pruebas.
Entonces, si usa este enfoque, debe almacenar el valor original y luego volverlo a configurar después de cada prueba.
Para hacer esto fácilmente con Jest, use el método
spyOn()
lugar de
jest.fn()
porque admite restaurar fácilmente su valor original, evitando así la ''fuga'' antes mencionada.
La pregunta ya está respondida, pero puede resolverla así:
dependency.js
module.exports.doSomething = (x) => x
myModule.js:
const { doSomething } = require(''./dependency'')
module.exports = (x) => doSomething(x * 2)
myModule.spec.js:
jest.mock(''../dependency'')
const { doSomething } = require(''../dependency'')
const myModule = require(''../myModule'')
describe(''myModule'', () => {
it(''calls the dependency with double the input'', () => {
doSomething.mockImplementation((x) => x * 10)
myModule(2);
expect(doSomething).toHaveBeenCalledWith(4);
console.log(myModule(2)) // 40
});
});
Para burlarse de una exportación predeterminada del módulo de dependencia ES6 usando jest:
import myModule from ''../myModule'';
import dependency from ''../dependency'';
jest.mock(''../dependency'');
// If necessary, you can place a mock implementation like this:
dependency.mockImplementation(() => 42);
describe(''myModule'', () => {
it(''calls the dependency once with double the input'', () => {
myModule(2);
expect(dependency).toHaveBeenCalledTimes(1);
expect(dependency).toHaveBeenCalledWith(4);
});
});
Las otras opciones no funcionaron para mi caso.
Resolví esto de otra manera. Digamos que tienes tu dependencia.js
export const myFunction = () => { }
Además, creo un archivo depdency.mock.js con el siguiente contenido:
export const mockFunction = jest.fn();
jest.mock(''dependency.js'', () => ({ myFunction: mockFunction }));
y en la prueba, antes de importar el archivo que tiene la dependencia que uso:
import { mockFunction } from ''dependency.mock''
import functionThatCallsDep from ''./tested-code''
it(''my test'', () => {
mockFunction.returnValue(false);
functionThatCallsDep();
expect(mockFunction).toHaveBeenCalled();
})
Tienes que burlarte del módulo y configurar el espía tú mismo:
import myModule from ''../myModule'';
import dependency from ''../dependency'';
jest.mock(''../dependency'', () => ({
doSomething: jest.fn()
}))
describe(''myModule'', () => {
it(''calls the dependency with double the input'', () => {
myModule(2);
expect(dependency.doSomething).toBeCalledWith(4);
});
});