Как я могу издеваться над импортом модуля ES6 с помощью Jest?
Я начинаю думать, что это невозможно, но я все равно хочу спросить.
Я хочу проверить, что один из моих модулей ES6 вызывает другой модуль ES6 определенным образом. С Жасмин это очень легко --
приложение код:
// myModule.js
import dependency from './dependency';
export default (x) => {
dependency.doSomething(x * 2);
}
и тестовый код:
//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);
});
});
что такое эквивалент с шуткой? Я чувствую, что это такая простая вещь, чтобы хотеть сделать, но я рвал свои волосы, пытаясь понять это.
в ближе всего я пришел, заменив importС requires, и перемещение их внутри тестов / функций. Ни то, ни другое я не хочу делать.
// 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);
});
});
для бонусных очков, я хотел бы, чтобы все это работало, когда функция внутри dependency.js экспорт по умолчанию. Однако я знаю, что шпионаж за экспортом по умолчанию не работает в Jasmine (или, по крайней мере, я никогда не мог заставить его работать), поэтому я не надеюсь, что это возможно в шутку.
4 ответов:
Я был в состоянии решить эту проблему с помощью взлома с участием
import *. Он даже работает как для именованных, так и для экспорта по умолчанию!для именованного экспорта:
// 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); }); });или для экспорта по умолчанию:
// 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 }); });как Михай Дамиан совершенно справедливо указал ниже, это мутация объекта модуля
dependency, и поэтому он будет "протекать" через другие тесты. Поэтому, если вы используете этот подход, вы должны сохранить исходное значение, а затем снова установить его после каждого теста. Делать это легко, с шуткой, используйте spyOn() вместоjest.fn()потому что он поддерживает легко восстанавливать свое первоначальное значение, поэтому избегая ранее упомянутой "утечки".
вы должны издеваться над модулем и установить шпиона самостоятельно:
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); }); });
добавление дополнительных ответов Андреаса. У меня была такая же проблема с кодом ES6, но я не хотел мутировать импорт. Это выглядело хаки. Так что я сделал это
import myModule from '../myModule'; import dependency from '../dependency'; jest.mock('../dependency'); describe('myModule', () => { it('calls the dependency with double the input', () => { myModule(2); }); });и добавлена зависимость.js in"__глумится __" папка параллельно зависимости.js. Это сработало для меня. Кроме того, это дало мне возможность вернуть подходящие данные из макетной реализации. Убедитесь, что вы даете правильный путь к модулю, который вы хотите издеваться.
чтобы издеваться над экспортом модуля зависимостей ES6 по умолчанию с помощью 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); }); });другие варианты не работали для моего случая.
Comments