QUnit, Sinon.js - How can I guarantee that Post to Fake Server has the correct request authority?

I have a JavaScript function that sends a message to the remote API that I am looking for to write unit test for. The method I want to test is as follows:

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 using Sinon.js) that checks if the callback is correct when the request succeeds:

 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 successfully returns no matter what the request body is. I want only Fake Server to respond if the request body is { one: 'one', two: 'two' }

+7
javascript unit-testing qunit sinon
source share
2 answers

I was going to suggest that you are using filtered queries . However, this is not possible with the current implementation of Sinon.

excerpt from the documentation:

Add a filter that will determine if the query should be faked. the filter will be called when xhr.open is called, with the same arguments ( method, url, async, username, password ). If the filter returns the truth, the request will not be tampered with.

You do not have the ability to filter data.

EDIT: If I understood the problem correctly, you could 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 the code will get the correct result that you want, but there is no way to programmatically accomplish this using Sinon right now.

+3
source share

Almost two years later, but still relevant:

This can be achieved by passing a function instead of an array as the third parameter in server.respondWith . The function accepts one argument "request", on which you can call request.respond(statusCode, headers, body);

You still have to retrieve the values ​​from request.requestBody , but at least this is possible.

 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'))); }); 
+10
source share

All Articles