Javascript sinon.js 1.10、jquery 2.1和同步请求
我尝试用sinon.js模拟服务器,并用Javascript sinon.js 1.10、jquery 2.1和同步请求,javascript,jquery,ajax,sinon,Javascript,Jquery,Ajax,Sinon,我尝试用sinon.js模拟服务器,并用jQuery.ajax调用它。但我不能让它工作 代码如下: $(function() { var server = sinon.fakeServer.create(); server.respondWith('POST', '/some/test', [200, { 'Content-Type' : 'application/json'}, JSON.stringify({ id : 'test', value : 'test'
jQuery.ajax
调用它。但我不能让它工作
代码如下:
$(function() {
var server = sinon.fakeServer.create();
server.respondWith('POST', '/some/test', [200, { 'Content-Type' : 'application/json'}, JSON.stringify({
id : 'test',
value : 'test'
})]);
var success = sinon.spy(),
error = sinon.spy();
jQuery.ajax({
url : '/some/test',
async : false,
type : 'POST',
data : JSON.stringify({
test : 'test'
}),
contentType : 'application/json',
success : success,
error : error,
});
console.log(server.requests[0].status);
console.log(server.requests[0].method);
console.log(server.requests[0].url);
console.log(server.requests[0].requestBody);
console.log(success.called);
console.log(error.called);
server.restore();
});
如果您尝试此代码,您将看到以下输出:
200
POST
/some/test
{"test":"test"}
false
false
根据前4条日志,sinon对请求进行了响应。但是jQuery从未调用成功回调(也没有调用错误)。
这就像jQuery ajax请求从未完成一样。问题来自于使用jQuery 2.1的sinon.js: jQuery 2.1发出如下同步ajax请求:
var req = new XMLHttpRequest();
req.open('POST', '/some/test', false);
req.setRequestHeader('Content-Type', 'application/json');
req.onload = function() {
console.log('success');
};
req.onerror = function() {
console.log('error');
};
req.send(JSON.stringify({
test : 'test'
}));
问题是Sinon不会触发同步请求的onload或onerror回调。问题在于FakeXMLHttpRequest
的方法setResponseBody
。您可以找到以下代码:
if (this.async) {
this.readyStateChange(FakeXMLHttpRequest.DONE);
} else {
this.readyState = FakeXMLHttpRequest.DONE;
}
在最近的浏览器中,XmlHttpRequest甚至会触发同步请求的回调。因此,应在以下情况下修改此代码:
if (!this.async) {
this.readyState = FakeXMLHttpRequest.DONE;
}
this.readyStateChange(FakeXMLHttpRequest.DONE);
如果您这样修补sinon.js,一切都会正常运行。问题来自使用jQuery 2.1的sinon.js: jQuery 2.1发出如下同步ajax请求:
var req = new XMLHttpRequest();
req.open('POST', '/some/test', false);
req.setRequestHeader('Content-Type', 'application/json');
req.onload = function() {
console.log('success');
};
req.onerror = function() {
console.log('error');
};
req.send(JSON.stringify({
test : 'test'
}));
问题是Sinon不会触发同步请求的onload或onerror回调。问题在于FakeXMLHttpRequest
的方法setResponseBody
。您可以找到以下代码:
if (this.async) {
this.readyStateChange(FakeXMLHttpRequest.DONE);
} else {
this.readyState = FakeXMLHttpRequest.DONE;
}
在最近的浏览器中,XmlHttpRequest甚至会触发同步请求的回调。因此,应在以下情况下修改此代码:
if (!this.async) {
this.readyState = FakeXMLHttpRequest.DONE;
}
this.readyStateChange(FakeXMLHttpRequest.DONE);
如果你这样修补sinon.js,一切都会正常。AJAX是异步的,当你调用控制台日志时,AJAX调用仍在处理中。即使选项中有一个
async:false
,我也没有看到。我不知道,async false是一个糟糕的做法,因此我从未使用过它。我知道这是一个糟糕的做法。但是我有一些。。。“遗留代码”,我无法更改:(即使没有jQuery,我也无法使用Sinon测试同步请求,经过一段时间的改进后,我决定禁用这些测试。如果我没记错的话(已经有一段时间了)Sinon没有为同步请求触发readystatechange事件,也没有在其模拟XMLHttpRequest对象上设置正确的完成状态。AJAX是异步的,当您调用控制台日志时,AJAX调用仍在处理中。即使选项中有一个async:false
,我也没有看到。我不知道,async false是一个错误糟糕的做法,因此我从未使用过它。我知道这是一个糟糕的做法。但我得到了一些…“遗留代码”,我无法改变它:(即使没有jQuery,我也无法使用Sinon测试同步请求,经过一段时间的研究,我决定禁用这些测试。如果我没有记错(已经有一段时间了)Sinon没有为同步请求触发readystatechange事件,也没有在其模拟XMLHttpRequest对象上设置正确的完成状态。