【问题标题】:How to get a sinon stub to call another function on nth call如何让 sinon 存根在第 n 次调用时调用另一个函数
【发布时间】:2016-12-16 22:50:52
【问题描述】:

我想使用 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()
    }

});

【问题讨论】:

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


    【解决方案1】:

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

    var cb = sinon.spy(completed);
    

    但是,如果由于某种原因从未调用事件处理程序,则测试将因超时而失败。

    【讨论】:

    • 完美,谢谢!我会更新我的问题。
    • 如何让它在第二次通话时回调?
    • @CoolBlue 你不能用间谍来做到这一点,只有存根(但是有了存根,你不能轻易地调用completed,所以这有点像第 22 条问题),虽然你可以在completed 中查看cb.callCount
    • 完美,谢谢。我再次更新了我的答案。看起来很干净。
    • 完美。感谢您花时间撰写有关如何捕获回调的文章。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 2016-07-11
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多