Как заглушить экспортированную функцию в ES6?
У меня есть файл foo.js:
export function bar (m) {
console.log(m);
}
И еще один файл, который использует foo.js, cap.js:
import { bar } from 'foo';
export default m => {
// Some logic that I need to test
bar(m);
}
У меня есть test.js:
import cap from 'cap'
describe('cap', () => {
it('should bar', () => {
cap('some');
});
});
Как-то мне нужно переопределить реализацию bar(m)
в тесте. Есть ли способ сделать это?
P.S. Я использую babel, webpack и mocha.
Ответы
Ответ 1
Ouch.. Я нашел решение, поэтому я использую sinon
для заглушки и import * as foo from 'foo'
, чтобы получить объект со всеми экспортируемыми функциями, чтобы я мог их заглушить.
import sinon from 'sinon';
import cap from 'cap';
import * as foo from 'foo';
sinon.stub(foo, 'bar', m => {
console.log('confirm', m);
});
describe('cap', () => {
it('should bar', () => {
cap('some');
});
});
Ответ 2
Вы можете экспортировать/переписывать/заглушать только из самого модуля. (Здесь объяснение)
Если вы переписываете 'foo.js' следующим образом:
var bar = function bar (m) {
console.log(m);
};
export {bar}
export function stub($stub) {
bar = $stub;
}
Затем вы можете переопределить его в своем тесте следующим образом:
import cap from 'cap'
import {stub} from 'foo'
describe('cap', () => {
it('should bar', () => {
stub(() => console.log('stubbed'));
cap('some'); // will output 'stubbed' in the console instead of 'some'
});
});
Я создал плагин Babel, который автоматически преобразует все экспортные файлы, чтобы их можно было заколоть: https://github.com/asapach/babel-plugin-rewire-exports
Ответ 3
Вы можете использовать babel-plugin-rewire (npm install --save-dev babel-plugin-rewire
)
И затем в test.js
используйте функцию __Rewire__
на импортированном модуле, чтобы заменить функцию в этом модуле:
// test.js
import sinon from 'sinon'
import cap from 'cap'
describe('cap', () => {
it('should bar', () => {
const barStub = sinon.stub().returns(42);
cap.__Rewire__('bar', barStub); // <-- Magic happens here
cap('some');
expect(barStub.calledOnce).to.be.true;
});
});
Обязательно добавьте rewire
к своим плагинам babel в .babelrc
:
// .babelrc
{
"presets": [
"es2015"
],
"plugins": [],
"env": {
"test": {
"plugins": [
"rewire"
]
}
}
}
Наконец, поскольку вы можете видеть, что плагин babel-plugin-rewire
включен только в тестовой среде, поэтому вы должны называть вас тестировщиком с переменной окружения BABEL_ENV
, установленной на test
(которую вы, вероятно, уже делаете)
env BABEL_ENV=test mocha --compilers js:babel-core/register test-example.js
Примечание. Я не мог заставить babel-plugin-rewire-exports
работать.