Sinon usefaketimer是一名名为miss miss的间谍

时间:2017-11-13 04:28:10

标签: unit-testing sinon

这是我的代码。我想测试"做"方法并验证带有时间间隔的this.obj.send被调用计数。

我的问题是当我存储_fetchAllDatas的方法并解决时。 this.obj.send无法调用。当this.obj.send移到_fetchAllDatas外面时。它可以被称为。

我该如何处理这个问题?谢谢〜

var sinon = require('sinon');


class A {
    constructor(obj){
        this.obj = obj;
        this.timer;
    }

    doing(){
        this.timer = setInterval(()=>{
            this._fetchAllDatas().then((data)=>{
                console.log('!!!',data);
                this.obj.send(data);
            });
        },1000)
    }

    stop(){
        clearInterval(this.timer);
    }

    _fetchAllDatas(){
        return Promise.resolve([]);
    }
}

var sandbox = sinon.sandbox.create();
var spy = { send: sandbox.spy()};
var a = new A(spy);
var stub = sandbox.stub(a,'_fetchAllDatas').resolves(['mark']);
var clock = sandbox.useFakeTimers();

a.doing();;
clock.tick(5000);
 sinon.assert.callCount(spy.send, 5); // error the count is zero. it should be 5 times

1 个答案:

答案 0 :(得分:0)

首先,"call count = 5 times within 5 seconds"的结果不会按预期发生。 这只是因为setInterval的回调将在N(ms)的延迟时间后触发; 也就是说,它只会在5s持续时间内发生四次,如下图所示:

x = not triggered
o = triggered

1s--1s--1s--1s--1s
x   o   o   o   o
^start          ^end

其次,在同步调用后,您无法立即从异步调用中获得正确的结果。 当您致电a.doing();时,它会启动setInterval的同步版本(因为useFakeTimers) 将调用函数this._fetchAllDatas() 返回一个运行异步回调的Promise, 这意味着this.obj.send(data)将异步执行。

即使你使用clock.tick(5000),它仍然是一个异步调用。

也就是说,你应该在Promise真正得到解决后的正确时间提出你的断言。