And*_*rew 10 javascript unit-testing jasmine karma-jasmine
我似乎无法能够窥探setTimeout和clearTimeout我的茉莉花测试,目前正通过噶运行.
我尝试了所有这些的变化
spyOn(window, 'setTimeout').and.callFake(()=>{});
spyOn(global, 'setTimeout').and.callFake(()=>{});
spyOn(window, 'clearTimeout').and.callThrough();
clock = jasmine.clock();
clock.install();
spyOn(clock, 'setTimeout').and.callThrough();
runMyCode();
expect(window.setTimeout).toHaveBeenCalled(); // no
expect(global.setTimeout).toHaveBeenCalled(); // nope
expect(window.clearTimeout).toHaveBeenCalled(); // no again
expect(clock.setTimeout).toHaveBeenCalled(); // and no
Run Code Online (Sandbox Code Playgroud)
在每种情况下,我都可以确认setTimeout并且clearTimeout已经被调用runMyCode,但我总是得到Expected spy setTimeout to have been called.
因为window,显然这是因为测试和跑步者(Karma窗口)处于不同的帧中(所以为什么我应该期待任何不同的).但正因为如此,我无法确定是否有任何方法可以确认这些全局函数已被调用.
我知道我可以jasmine.clock()用来确认已经调用了超时/间隔回调,但看起来我看不到setTimeout自己.确认clearTimeout被称为简单是不可能的.
在这一点上,我唯一能想到的是添加一个单独的抽象层来包装setTimeout和/ clearTimeout或注入函数作为依赖项,我以前做过,但我觉得很奇怪.
小智 5
我能够使它像这样工作:
spyOn(window, 'setTimeout');
runMyCode();
expect(setTimeout).toHaveBeenCalled();
Run Code Online (Sandbox Code Playgroud)
只需从setTimeout调用中删除“窗口”对象即可。
编辑:自从问这个问题以来,看起来 Jasmine 已经实现了Clock,这使得这种模拟成为可能。而且,正如 Piotr Jaworski 的回答所指出的,Facebook 的基于 Jasmine 的 Jest 提供了自己的(可以说更好的)方式来模拟和监视定时任务。
所以,答案的其余部分已过时......
我能找到的唯一解决方案是使用Rewire(就我而言,我还需要使用Rewire-Webpack)。
Rewire 确实允许您替换全局方法——但是一旦方法被替换,它就无法被监视。因此,要真正成功使用toHaveBeenCalledWith,您必须包装并代理模拟函数。
var rewire = require('rewire'),
myModule = rewire('./path/to/module');
describe(function () {
var mocks = {
setTimeout: function () { return 99: },
clearTimeout: function () {}
};
beforeEach(function () {
// This will work
myModule.__set__('setTimeout', function () {
mocks.setTimeout.apply(null, arguments)
})
// This will NOT work
myModule.__set__('clearTimeout', mocks.clearTimeout)
});
it('calls setTimeout', function () {
spyOn(mocks, 'setTimeout').and.callThrough();
spyOn(mocks, 'clearTimeout').and.callThrough();
myModule.doSomething(); // this will invoke setTimeout locally
expect(mocks.setTimeout).toHaveBeenCalledWith(jasmine.any(Function), 1000);
expect(mocks.clearTimeout).toHaveBeenCalledWith(99); // Won't work (see above)
});
});
Run Code Online (Sandbox Code Playgroud)
当然,下次 Jasmine、Rewire、Karma、Webpack... 或天气... 发生变化时,这肯定会停止工作(grrr)。如果这对您不起作用,请发表评论,以便未来的开发人员知道。
| 归档时间: |
|
| 查看次数: |
7637 次 |
| 最近记录: |