Этот синтаксис:
import something from 'myModule';
... - это синтаксис ES6, который связывает something
с default
экспортом 'myModule
'.
Если модуль является модулем ES6, вы можете заблокировать default
экспорт модуля следующим образом:
import * as myModule from 'myModule';
const sinon = require('sinon');
// ...
const stub = sinon.stub(myModule, 'default');
... но это работает, только если 'myModule'
является модулем ES6.
В этом случае 'lodash/debounce'
не является модулем ES6, он поставляется предварительно скомпилированным. Последняя строка такова:
module.exports = debounce;
... что означает, что экспорт модуля равен функции debounce.
Это означает, что для того, чтобы заглушить 'lodash/debounce'
, вам нужно смоделировать весь модуль.
Sinon не обеспечивает насмешки на уровне модулей, поэтому вам нужно использовать что-то вроде proxyquire
:
const proxyquire = require('proxyquire');
const sinon = require('sinon');
const debounceStub = sinon.stub().returnsArg(0);
const code = proxyquire('[path to your code]', { 'lodash/debounce': debounceStub })
... или если вы используете Jest
, вы можете использовать что-то вроде jest.mock
:
jest.mock('lodash/debounce', () =>
jest.fn((func, ms) => func) // <= mock debounce to simply return the function
);
Детали
Причина, по которой сохранение модуля экспорта default
работает только в том случае, если это модуль ES6, вызвана тем, что происходит во время компиляции.
Синтаксис ES6 компилируется в пре-ES6 JavaScript. Например, Бабель превращает это:
import something from 'myModule';
... в это:
var _myModule = _interopRequireDefault(require("myModule"));
function _interopRequireDefault(obj) {
return obj && obj.__esModule ?
obj : // <= return the result of require("myModule") if it is an ES6 module...
{ default: obj }; // <= otherwise set it to the default property of a wrapper object
}
... поэтому, если 'myModule'
является модулем ES6, он возвращается напрямую ... но если это не так, то взаимодействие возвращает объект переноса.
Поскольку каждый import
получает свой объект-обертку, изменение свойства default
для одного не влияет на свойство default
для других.