仅在闭包中定义的模拟/存根对象
Mocking/stubbing objects that are only defined in a closure
首先,为了测试我的库,我正在使用摩卡和柴,但有时我可能也需要Sinon。
这是库:
import Service from 'service'; // a third-party module out of my control
const service = Service(...);
class MyLib {
... uses `service` in a bunch of different ways ...
... service.put(foo) ...
... service.get(bar) ...
}
export default MyLib;
这基本上是测试文件:
import MyLib from '../my-lib.js';
describe('MyLib', () => {
describe('a method that uses the service', () => {
...
service
对象对远程服务器进行一些调用,这在测试中我无法真正做到。因此,我认为我应该存根服务的方法或模拟整个服务对象。但是,由于对象是恒定的,只能通过MyLib
闭包到达,我不知道如何。
理想情况下,我不希望更改MyLib
的 API,例如在构造函数中注入服务对象。
如果重要的话,我将 Babel 6 与 es2015
预设一起使用。
我应该如何处理这个问题?
有几种方法可以做到这一点。
最简单的方法,无需额外的库
将服务另存为类属性并从那里调用它:
import Service from 'service';
const service = Service(...);
class MyLib {
constructor() {
this.service = service;
}
... now you should call service in a bit different way
... this.service.put(foo) ...
... this.service.get(bar) ...
}
export default MyLib;
然后,您可以在测试中重写服务实例:
it('should call my mock', () => {
const lib = new MyLib();
lib.service = mockedService; // you need to setup this mock, with Sinon, for example
lib.doSomething();
assert.ok(mockedService.put.calledOnce); // works
});
模拟要求() 函数
有一些库允许您覆盖require()
函数的结果。我最喜欢的是代理奎尔。你可以使用它,你的模块将被嘲笑而不是真实的:
import proxyquire from 'proxyquire';
it('should call my mock', () => {
const MyLib = proxyquire('./my-lib', {
// pass here the map of mocked imports
service: mockedService
})
const lib = new MyLib();
lib.doSomething();
assert.ok(mockedService.put.calledOnce); // works
});
使用rewire
访问模块闭合
Rewire是一个特殊的库,用于检测模块代码,因此您可以更改其中的任何局部变量
import rewire from 'rewire';
it('should call my mock', () => {
const MyLib = rewire('./my-lib')
const lib = new MyLib();
// __set__ is a special secret method added by rewire
MyLib.__set__('service', mockedService);
lib.doSomething();
assert.ok(mockedService.put.calledOnce); // works
});
此外,还有一个 babel-plugin-rewire,可以更好地与您的工具集成。
上述所有方法都很好,您可以选择更适合您的问题的方法。
我最近也在处理同样的事情。您可以利用 https://nodejs.org/api/modules.html#modules_caching在正在编写的测试中,按照在要测试的文件中相同的方式要求/导入服务。然后使用 Sinon 存根您在文件中使用的方法进行测试。
sinon.stub(Service, put).returns()
当文件需要服务时,它将使用修改后的模块。
我还没有测试您的确切情况,您正在创建服务的实例,然后才使用它,但是玩一下它应该可以帮助您实现您想要的,而且这一切都没有任何外部库,只有简单的 sinon 存根。
你的MyLib
测试不应该测试service
,所以我建议嘲笑全部或大部分。您应该检查MyLib
是否使用正确的参数在service
上调用了正确的函数。
我不确定 sinon,但这看起来像是导入和使用库的一种非常标准的方式,如果它不支持嘲笑service
,我会感到惊讶。
- 在VanillaJS中模拟模型双向数据绑定
- 使用jasmine模拟对服务器的调用
- 模拟谷歌地图中的点击
- 使用模拟按键在输入框中自动输入文本
- 模拟chrome.storage.local函数使用Jasmine
- 从数据库中检索字段,而不模拟它们
- 未调用 Sinon 存根
- 如何侦察内部存根返回与西农
- react testUtils模拟点击单选按钮而不触发onchange
- 如何在ember单元测试中模拟_super()方法
- Javascript中对象的每个()的模拟值
- 模拟<按钮>在<asp:button>
- javascript上的数字类型模拟
- 在Android Kitkat上模拟鼠标点击Youtube视频
- Webscratching自动化如何在没有链接TAG的情况下模拟点击HREF链接
- 用jQuery模拟点击
- 单元测试:使用酶模拟父组件中子组件的点击事件
- sails.js中的模拟/存根全局变量
- 仅在闭包中定义的模拟/存根对象
- 如何使用 sinon 存根/模拟从“超类”复制的依赖项方法