1

我无法理解 sinonjs 间谍的行为。

这是我的测试:

asyncTest('sinon async spies test', 
function() { 

    var pApi = 
    { 
        product: function(id, options) { 
            var d = { o: 'a result' };
            options.success(d);
            return d;
        },
    };

    this.spy(pApi, 'product');
    pApi.product(1, { success: function(data) {} });

    //Assertion 1
    ok(pApi.product.calledOnce, 'product API called: ' + 
        pApi.product.calledOnce);

    setTimeout(
            function() { 
                //Assertion 2
                ok(pApi.product.calledOnce, 
                    'product function called once (calledOnce: ' +   
                     pApi.product.calledOnce + ')');
                start();
            }, 1000);

});

使用 qunit 和 sinonjs(通过 sinon-qunit)运行上述测试,我通过了断言 1,但断言 2 失败(在 setTimeout 回调中)。事实上,当我们pApi.product.calledOnce在控制台中记录 的值时(通过断言的消息完成),它是undefined.

注意:我的测试文件顶部有这个:

sinon.config.useFakeTimers = false;

谁能解释这种奇怪的行为?不应该pApi.product在 setTimeout 回调中并且没有两者都calledOnce作为间谍的有效属性吗?

更新

基于http://api.qunitjs.com/asyncTest/,我弄清楚了为什么会显示上述行为。

asyncTeststart()在调用函数之前不会运行 testrunner 。当我更改this.spy(pApi, 'product')sinon.spy(pApi, 'product'). 显然,是否test使用 is 而不是asyncTest,这会影响该this.spy方法的运行时间。

需要实际查看 sinon、qunit 和 sinon-qunit 代码才能弄清楚这一点。

4

1 回答 1

2

您应该将间谍分配给一个变量,并使用它来断言 calledOnce:

asyncTest('sinon async spies test', function() { 
    var pApi = { 
        product: function(id, options) { 
            var d = { o: 'a result' };
            options.success(d);
            return d;
        }
    };

    var pApiSpy = this.spy(pApi, 'product');
    pApi.product(1, { success: function(data) {} });

    //Assertion 1
    ok(pApiSpy.calledOnce, 'product API called');

    setTimeout(
            function() { 
                //Assertion 2
                ok(pApiSpy.calledOnce, 
                    'product function called once');
                start();
            }, 1000);

});

这将通过两个断言。我认为问题与Sinon在测试功能结束时恢复方法有关,即使QUnit仍在等待start()指示测试完成。当你的 timeout 函数被调用时,pApi.product它不再是一个 spy 对象,所以它没有 calledOnce 属性。将 spy 设置为其自己的变量允许您对其进行处理,直到调用超时。

于 2013-01-06T20:21:50.147 回答