如何让一个sinon存根在第n次调用时调用另一个函数

时间:2016-08-10 13:49:50

标签: node.js asynchronous mocha sinon sinon-chai

我想使用一个sinon存根来异步测试一个事件发射器。 我希望存根在调用后调用回调。

我认为stub.yields是我想要的但不是。有没有一个巧妙的方法来做到这一点?

    it('asynchronously emits finish after logging is complete', function(done){
        const EE = require('events');
        const testEmitter = new EE();

        var cb = sinon.stub();
        cb.calls(completed);    // no such method but this is what I need

        testEmitter.on('finish', cb.bind(null));

        testEmitter.emit('finish');

        function completed() {

            expect(cb).to.have.been.calledOnce;
            expect(cb).to.have.been.calledOn(null);
            expect(cb).to.have.exactArgs();

            done()
        }

    });

目前,我正在做这样的事情......

        it('asynchronously emits finish', function(done) {
            const EE = require('events');
            const testEmitter = new EE();
            var count = 1;

            process.nextTick(() => testEmitter.emit('finish'));

            function cb(e) {
                var self = this;
                expect(e).to.be.an('undefined');
                expect(self).to.equal(testEmitter);
                if(!count--)
                    done()
            }

            testEmitter.on('finish', cb);

            process.nextTick(() => testEmitter.emit('finish'));

        });

它工作正常,但我需要概括它,我认为我可以用sinon更有效地做到这一点。但我无法弄清楚如何从sinon docs中做到这一点。我错过了什么吗?

感谢Robert Klep,这是解决方案......

it('asynchronously emits finish after logging is complete', function(done){
    const EE = require('events');
    const testEmitter = new EE();

    var cb = sinon.spy(completed);

    process.nextTick(() => testEmitter.emit('finish'));

    testEmitter.on('finish', cb.bind(null));

    process.nextTick(() => testEmitter.emit('finish'));

    function completed() {

        if(cb.callCount < 2)
            return;

        expect(cb).to.have.been.calledTwice;
        expect(cb).to.have.been.calledOn(null);
        expect(cb).to.have.been.calledWithExactly();

        done()
    }

});

1 个答案:

答案 0 :(得分:2)

你可以使用间谍,因为间谍会调用他们正在监视的功能:

var cb = sinon.spy(completed);

但是,由于某种原因,事件处理程序永远不会被调用,测试将因超时而失败。