Javascript 如何在 ES6 中存根导出的函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34575750/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stub exported function in ES6?
提问by Mike Chaliy
I have file foo.js:
我有文件 foo.js:
export function bar (m) {
console.log(m);
}
And another file that uses foo.js, cap.js:
另一个使用 foo.js 的文件 cap.js:
import { bar } from 'foo';
export default m => {
// Some logic that I need to test
bar(m);
}
I have test.js:
我有 test.js:
import cap from 'cap'
describe('cap', () => {
it('should bar', () => {
cap('some');
});
});
Somehow I need override implementation of bar(m)
in test. Is there any way to do this?
不知何故,我需要覆盖bar(m)
测试中的实现。有没有办法做到这一点?
P.S. I use babel, webpack and mocha.
PS 我使用 babel、webpack 和 mocha。
回答by Mike Chaliy
Ouch.. I found solution, so I use sinon
to stub and import * as foo from 'foo'
to get object with all exported functions so I can stub them.
哎哟..我找到了解决方案,所以我使用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');
});
});
回答by DreamSonic
You can replace/rewrite/stub exports only from within the module itself. (Here's an explanation)
您只能从模块本身内部替换/重写/存根导出。(这里有一个解释)
If you rewrite 'foo.js' like this:
如果你像这样重写'foo.js':
var bar = function bar (m) {
console.log(m);
};
export {bar}
export function stub($stub) {
bar = $stub;
}
You can then override it in your test like this:
然后,您可以像这样在测试中覆盖它:
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'
});
});
I've created a Babel plugin that transforms all the exports automatically so that they can be stubbed: https://github.com/asapach/babel-plugin-rewire-exports
我创建了一个 Babel 插件,可以自动转换所有导出,以便它们可以被存根:https: //github.com/asapach/babel-plugin-rewire-exports
回答by Daniel Conde Marin
While @Mike solution would work in old versions of sinon, it has been removed since sinon 3.0.0.
虽然@Mike 解决方案适用于旧版本的 sinon,但它已从 sinon 3.0.0 中删除。
Now instead of:
现在代替:
sinon.stub(obj, "meth", fn);
you should do:
你应该做:
stub(obj, 'meth').callsFake(fn)
Example of mocking google oauth api:
模拟 google oauth api 的示例:
import google from 'googleapis';
const oauth2Stub = sinon.stub();
sinon.stub(google, 'oauth2').callsFake(oauth2Stub);
oauth2Stub.withArgs('v2').returns({
tokeninfo: (accessToken, params, callback) => {
callback(null, { email: '[email protected]' }); // callback with expected result
}
});
回答by qff
You can use babel-plugin-rewire(npm install --save-dev babel-plugin-rewire
)
你可以使用babel-plugin-rewire( npm install --save-dev babel-plugin-rewire
)
And then in test.js
use the __Rewire__
function on the imported module to replace the function in that module:
然后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;
});
});
Be sure to add rewire
to your babel plugins in .babelrc
:
一定要添加rewire
到你的 babel 插件中.babelrc
:
// .babelrc
{
"presets": [
"es2015"
],
"plugins": [],
"env": {
"test": {
"plugins": [
"rewire"
]
}
}
}
Lastly, as you can see the babel-plugin-rewire
plugin is only enabled in the test environment, so you should call you test runner with the BABEL_ENV
environment variable set to test
(which you're probably doing already):
最后,正如您所看到的,该babel-plugin-rewire
插件仅在测试环境中启用,因此您应该调用测试运行程序并将BABEL_ENV
环境变量设置为test
(您可能已经这样做了):
env BABEL_ENV=test mocha --compilers js:babel-core/register test-example.js
Note: I couldn't get babel-plugin-rewire-exports
to work.
注意:我无法babel-plugin-rewire-exports
上班。