[英]Stubbing single exported function with Sinon
我刚刚改变了我的 lodash import from import _ from 'lodash';
import debounce from 'lodash/debounce';
在我的测试中,我曾经使用过sandbox.stub(_, 'debounce').returnsArg(0);
,但现在我不知道将其更改为什么。 显然sandbox.stub(debounce).returnsArg(0);
不会工作。 当模块中只导出一个函数时,不确定该怎么做。
此语法:
import something from 'myModule';
...是 ES6 语法,它将something
内容绑定到'myModule
”的default
导出。
如果模块是 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
类的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
);
细节
仅当模块是 ES6 模块时才对模块的default
导出进行存根的原因是因为编译期间发生了什么。
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
任何他人财产。
你可以自己制作一个包装文件,它最终会为你导出相同的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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.