我有一个JavaScript函数,它发布了一个远程API,我正在编写单元测试。我想测试的方法是:
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);
});
}
我有一个单元测试(在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')));
});
此测试有效,但无论请求正文是什么,它都会成功返回。我想要做的只是在请求正文为{ one: 'one', two: 'two' }
答案 0 :(得分:12)
差不多两年后,但仍然相关:
这可以通过将函数而不是数组作为第三个参数传递给server.respondWith
来实现。该函数接受一个参数'request',您可以在其上调用request.respond(statusCode, headers, body);
你仍然需要从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')));
});
答案 1 :(得分:3)
我打算建议您使用filtered requests。然而,对于sinon的当前实现,这是不可能的。
摘自文档:
添加一个过滤器,用于决定是否伪造请求。该 调用xhr.open时将调用filter,完全相同 参数(方法,网址,异步,用户名,密码)。如果是过滤器 返回truthy,请求不会被伪造。
您无法过滤数据。
编辑:如果我正确理解了问题,你可能会做这样的事情:
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));
}
我知道代码会得到你想要的正确结果,但目前还没有办法用sinon以编程方式完成它。