简体   繁体   English

QUnit,Sinon.js - 我如何确保Post-Fake Server有正确的请求体?

[英]QUnit, Sinon.js - How do I ensure Post to Fake Server has correct request body?

I have a JavaScript function that does a Post to a remote API that I am looking at writing a unit test for. 我有一个JavaScript函数,它发布了一个远程API,我正在编写单元测试。 The method I want to test is this: 我想测试的方法是这样的:

var functionToTest = function(callback, fail) {
    $.ajax({
        url: "/myapi/",
        type: "POST",
        data: { one: 'one', two: 'two' },
        accept: "application/json",
        contentType: "application/json"
    }).done(function(x) {
        log = generateLogMessage('Success');
        callback(log);
    }).fail(function(x, s, e) {
        log = generateLogMessage('Fail');
        fail(log);
    });
}

I have a unit test (in QUnit leveraging Sinon.js) that tests that the callback is called correctly when the request succeeds: 我有一个单元测试(在QUnit中利用Sinon.js)测试在请求成功时正确调用回调:

QUnit.test('Test that the thing works', function () {

    var server = this.sandbox.useFakeServer();

    server.respondWith(
        'POST',
        '/myapi/',
        [
            200,
            {'Content-Type': 'application/json'},
            '{"Success":true}'
        ]
    );

    var callback = this.spy();
    functionToTest(callback, callback);
    server.respond();

    QUnit.ok(callback.calledWith(generateLogMessage('Success')));
});

This test works, but it returns successfully regardless of what the request body. 此测试有效,但无论请求主体是什么,它都会成功返回。 What I want to do is only have the Fake Server respond if the request body is { one: 'one', two: 'two' } 如果请求正文是{ one: 'one', two: 'two' }我想要做的只是让假服务器响应

Almost two years later now, but still relevant: 差不多两年后,但仍然相关:

This can be achieved by passing a function instead of an array as the third parameter to server.respondWith . 这可以通过将函数而不是数组作为第三个参数传递给server.respondWith The function takes one argument 'request', on which you can call request.respond(statusCode, headers, body); 该函数接受一个参数'request',您可以在其上调用request.respond(statusCode, headers, body);

You'll still have to extract the values from request.requestBody , but at least it's doable. 你仍然需要从request.requestBody提取值,但至少它是可行的。

QUnit.test('Test that the thing works', function () {

    var server = this.sandbox.useFakeServer();

    server.respondWith(
        'POST',
        '/myapi/',
        function (request) {
            console.log(request.requestBody); // <- assert here :-)
            request.respond(200, {'Content-Type': 'application/json'}, '{"Success":true}');
        }
    );

    var callback = this.spy();
    functionToTest(callback, callback);
    server.respond();

    QUnit.ok(callback.calledWith(generateLogMessage('Success')));
});

I was going to suggest that you use filtered requests . 我打算建议你使用过滤的请求 However this is not possible with the current implementation of sinon. 然而,对于sinon的当前实现,这是不可能的。

excerpt from documentation: 摘自文件:

Add a filter that will decide whether or not to fake a request. 添加一个过滤器,决定是否伪造请求。 The filter will be called when xhr.open is called, with the exact same arguments ( method, url, async, username, password ). 调用xhr.open时将调用过滤器,并使用完全相同的参数( method,url,async,username,password )。 If the filter returns truthy, the request will not be faked. 如果过滤器返回truthy,请求将不会被伪造。

You don't have ability to filter on the data. 您无法过滤数据。

EDIT: If I understand the problem correctly, you might be able to do something like this: 编辑:如果我正确理解问题,你可能会做这样的事情:

functionToTest(...);
var request = server.requests[0];
var data = JSON.parse(request.requestBody);
if (data.one == 'one' && data.two == 'two') {
  request.respond(200, jsonHeaders, JSON.stringify(specialResponse));
}
else {
  request.respond(200, jsonHeaders, JSON.stringify(otherResponse));
}

I know that code will get the correct result that you want, but there's not a way to programmatically accomplish that with sinon right now. 我知道代码会得到你想要的正确结果,但现在还没有办法用sinon以编程方式完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM