我怎样才能让sinon屈服于多次回调

时间:2014-12-16 17:08:21

标签: javascript ajax sinon

我正在尝试存根几个ajax调用,但我想同时执行beforeSend和成功,这可能吗?

我想要这样的事情:

var stub = sinon.stub(jQuery, "ajax");
stub.onCall(0).yieldsTo("beforeSend").yieldsTo("success", {some: 'data'});
stub.onCall(1).yieldsTo("beforeSend").yieldsTo("success", {other: 'stuff'});

但这会在发送之前跳过'方法

我知道允许ajax做这件事并使用sinon的fakeServer会更容易,但我无法在Node中使用假浏览器进行测试它只是doesn't work

2 个答案:

答案 0 :(得分:0)

您可以在通话后使用yieldTo

var stub = sinon.stub();
stub({
    foo: function() {
        console.log('foo');
    },
    bar: function() {
        console.log('bar');
    }
});
stub.yieldTo('foo');
stub.yieldTo('bar');

答案 1 :(得分:0)

我能够通过添加一些额外的代码来解决这个问题:

var responses = {};
var executionComplete;

beforeEach(function () {
    executionComplete = $.Deferred();
    sinon.stub($, "ajax", function (options) {
        if (options.beforeSend) {
            options.beforeSend();
        }
        completeAjaxCall(options);
    });
});

afterEach(function () {
    $.ajax.restore();
});

var completeAjaxCall = function (options) {
    var response = findResponse(options.url, options.type);
    setTimeout(function () {
        if (response.code < 400) {
            if (options.dataFilter && response.data) {
                response.data = options.dataFilter(JSON.stringify(response.data));
            }
            if (options.success) {
                options.success(response.data);
            }
        } else {
            if (options.error) {
                options.error(response.data);
            }
        }
        if (options.complete) {
            options.complete();
        }
        if (response.completeExecution) {
            executionComplete.resolve();
        }
    }, response.serverResponseTime);
};

var findResponse = function (url, type) {
    var response = responses[url];
    expect(response, url + ' should have a response').to.exist;
    expect(response.type).to.equal(type);
    delete responses[url];
    if (Object.keys(responses).length === 0) {
        response.completeExecution = true;
    }
    return response;
};

var givenResponse = function (response) {
    responses[response.url] = response;
};

然后在我的测试中我可以像这样使用它:

it('should do some stuff', function (done) {
    //given
    givenResponse({serverResponseTime: 4, code: 200, url: '/saveStuff', type: 'POST'});
    givenResponse({serverResponseTime: 1, code: 200, url: '/getStuff', type: 'GET'});

    //when
    $('button').click();

    //then
    executionComplete.then(function () {
        expect(something).to.be.true;
        done();
    });
});