2 回答

TA貢獻1784條經驗 獲得超2個贊
此語法:
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;
...這意味著模塊導出是去抖動功能。
這意味著為了存根,'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。例如,Babel 變成了這樣:
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任何其他對象的屬性。

TA貢獻1780條經驗 獲得超4個贊
你可以自己制作一個包裝文件,它最終會lodash/debounce為你導出同一個實例,但這次你可以存根,例如:
myutils/lodash/debounce.js
import lodashDebounce from 'lodash/debounce';
const exports = {
debounce: lodashDebounce,
};
export const debounce = () => exports.debounce();
export default exports;
現在,在您的實際代碼中,debounce不是從原始位置導入,而是從這個包裝文件導入:
前:
import debounce from 'lodash/debounce' // this is how we usually do
后:
import { debounce } from 'myutils/lodash/debounce' // if we want to stub it
// all other code-lines remain the same
const method = () => {
debounce(callback, 150));
...
}
現在在做test.js 時:
import lodashWrapped from 'myutils/lodash/debounce';
sinon.stub(lodashWrapped , 'debounce').callsFake((callbackFn) => {
// this is stubbed now
});
// go on, make your tests now
添加回答
舉報