Javascript 如何在Sinon JS中延迟假后端的特定响应
在我的应用程序中,我使用主干框架。Karma,Jasmine,SinonJS-用于测试 我有一个简单的主干视图,如下所示:Javascript 如何在Sinon JS中延迟假后端的特定响应,javascript,jquery,backbone.js,jasmine,sinon,Javascript,Jquery,Backbone.js,Jasmine,Sinon,在我的应用程序中,我使用主干框架。Karma,Jasmine,SinonJS-用于测试 我有一个简单的主干视图,如下所示: View = Backbone.View.extend({ el: ‘#app’, initialize: function () { var collection1 = new Collection1();// creates collection which can receive data from backend va
View = Backbone.View.extend({
el: ‘#app’,
initialize: function () {
var collection1 = new Collection1();// creates collection which can receive data from backend
var collection2 = new Collection2(); // another one
collection1.fetch().done(function() { // backbone sends the request for data to backend
//render data1 which received from backend and append to el
});
collection2.fetch().done(function() {
//render data2 which received from backend and append to el
});
}
});
define(function(require) {
//get all dependencies
describe('test ', function() {
var view = null,
server = null;
beforeAll(function(done) { // need to save view beetwen requests, change to beforeAll
server = sinon.fakeServer.create(); // fake sinon server
view = new View(); // create Backbone View
done(); // run this jasmine-method to say jasmine - "All is good, run immediately tests in it-sections"
});
afterAll(function() {
server.restore();
view = null;
});
it('run response for second request by firstly', function() {
server.secondRequest.respond(200,
{"Content-Type": "application/json"},
mockData2);
// in this section need to use expect and check state of view
});
it('run response for first request by secondly', function() {
server.firstRequest.respond(200,
{"Content-Type": "application/json"},
mockData1);
// in this section need to use expect and check state of view
});
});
});
两个集合发送不同的请求(不同的URL)
我需要测试这段代码,我需要确定collection2将在collection1之后从后端返回数据的情况。这种情况需要得到保证。这是这次测试的主要内容
我知道如何延迟所有伪造后端的请求,但我不知道如何延迟其中一个请求
我使用异步测试
我的测试代码:
define(function(require) {
//get all dependencies
function testAsync(delayTime) { // make delay
var deferred = $.Deferred();
setTimeout(function() {
deferred.resolve();
}, delayTime);
return deferred.promise();
}
describe('test ', function() {
var view = null,
server = null;
beforeEach(function(done) {
server = sinon.fakeServer.create(); // fake sinon server
server.autoRespond = true; // enable autoanswer
testAsync(3000) // delay 3 sec
.done(function(done) {
server.respondWith('GET', urlsForRequest.collection1, [
200,
{"Content-Type": "application/json"},
mockData1]);
server.respondWith('GET', urlsForRequest.collection2, [
200,
{"Content-Type": "application/json"},
mockData2]);
done(); // all is good go to it section, it's a jasmine func
});
view = new View(); // create Backbone View
});
afterEach(function() {
server.restore();
});
it('can be instantiated', function() {
// in this section need to use expect
});
});
});
此测试延迟了所有响应,但我只需要延迟一个响应
如何更改此代码以实现正确的测试
T.J.私人秘书。
我试着使用这个代码,结果是一样的
server.respondWith('GET', urlsForRequest.collection2, function(fakeRequest) {
fakeRequest.autoRespond = true;
fakeRequest.autoRespondAfter = 3000;
fakeRequest.respond(200, {"Content-Type": "application/json"}, mockData2);
done();
});
您不应该设置
server.autoRespond=true代码>在这种情况下。此外,您不需要使用testAsync
功能,因为sinon已经为它内置了选项(如果必要):server.autorespondeafter
只要回应你想先成功的请求
server.respondWith('GET', urlsForRequest.collection1, [
200,
{"Content-Type": "application/json"},
mockData1]);
然后响应第二个请求,可能会将其包装为超时,以确保在前一个请求之后将其添加到队列:
setTimeout(function(){
server.respondWith('GET', urlsForRequest.collection2, [
200,
{"Content-Type": "application/json"},
mockData2]);
}, 0);
如果由于某种原因,这不起作用,那么最终您必须:
布尔请求.async
请求是否是异步的
为了测试的目的,您可以使它们同步,以确保一个接一个的完成。好的,我的解决方案就是这样
首先,我禁用了所有autoRespond
选项,并删除了手动响应的server.respond()
调试后的下一步,我在假服务器选项中找到了-队列
。如果您有很多请求,则此队列具有一个数组,其中包含所有对假服务器的假请求。存在特殊选项(firstRequest
、secondRequest
、thirdRequest
和lastRequest
)。每个fakeRequest都有方法respond(code,contentType对象,body)
,您可以使用它手动发送特定请求的响应
因此,我的测试代码在所有更改实现后如下所示:
View = Backbone.View.extend({
el: ‘#app’,
initialize: function () {
var collection1 = new Collection1();// creates collection which can receive data from backend
var collection2 = new Collection2(); // another one
collection1.fetch().done(function() { // backbone sends the request for data to backend
//render data1 which received from backend and append to el
});
collection2.fetch().done(function() {
//render data2 which received from backend and append to el
});
}
});
define(function(require) {
//get all dependencies
describe('test ', function() {
var view = null,
server = null;
beforeAll(function(done) { // need to save view beetwen requests, change to beforeAll
server = sinon.fakeServer.create(); // fake sinon server
view = new View(); // create Backbone View
done(); // run this jasmine-method to say jasmine - "All is good, run immediately tests in it-sections"
});
afterAll(function() {
server.restore();
view = null;
});
it('run response for second request by firstly', function() {
server.secondRequest.respond(200,
{"Content-Type": "application/json"},
mockData2);
// in this section need to use expect and check state of view
});
it('run response for first request by secondly', function() {
server.firstRequest.respond(200,
{"Content-Type": "application/json"},
mockData1);
// in this section need to use expect and check state of view
});
});
});
我的德夫德普:
"devDependencies": {
"jasmine-core": "^2.6.4",
"karma": "^1.7.0",
"karma-chrome-launcher": "^2.2.0",
"karma-jasmine": "^1.1.0",
"karma-phantomjs-launcher": "^1.0.4",
"karma-requirejs": "^1.1.0",
"karma-sinon": "^1.0.5",
"sinon": "^2.3.6"
}
我尝试使用setTimeout,但在它的部分中,我没有collection2的数据。这不是工作。接下来,我尝试在fakeRequest中使用autorespondAfter。结果是一样的。将代码添加到我的主消息中。FakeRequest的async=true选项我在回答中说不要使用autoRespond
或autorespondeafter
,但您正在使用它。它们是服务器的属性,但您正在请求中设置它们,我不知道为什么。我不明白做了什么()代码>在更新的代码中用于。最后,如果所有其他操作都失败,我提到可以使用async
选项使请求同步。但您将其设置为true
,并保持其异步。你正在做一系列的事情,但都做错了,请仔细阅读答案,逐个做,删除我在所有方法中使用的不必要的代码和属性。有、无自动响应自动响应。我过去常常像你说的那样设置超时——这不管用。当我在没有设置超时的情况下运行时。假服务器获取异步应答,但第一个collection1.fetch(10毫秒后)和第二个collection2.fetch(10毫秒后)。10ms-这是异步响应的默认延迟。若我在setTimeout func中运行second responseWith,那个么我只收到来自first的响应,而来自second response的数据并没有预先设置在“it”部分。我在文档中找不到任何文字说明如何实现一个请求的默认延迟(10毫秒),另一个请求的默认延迟为3000毫秒。问题可能是您想到了与真实服务器类似的假服务器,试图按照真实世界中发生的情况执行测试。它是一个伪造服务器,当您告诉它响应时,它只响应匹配的请求。因此,您可以发送请求,告诉服务器响应,发送另一个请求,告诉服务器响应。因此,您可以按照希望的顺序获得请求响应,就这么简单。您可能正在使用与其他测试相同的fakeserver实例,该实例设置为自动响应请求等。在应用程序外部创建一个小测试,测试我上面提到的内容。是的,我考虑过这种方法。但是,在新南威尔士州,如果我理解正确的话。存在两种发送响应的方式。First-config autoRespond=true。发送请求时,默认情况下,fakeServer在10毫秒后发送异步响应。其次,当您使用server.respond()方法手动发送respond时。此方法发送队列中所有请求的响应。我不知道如何手动响应特定请求:(据我所知,done()
用于处理异步操作,例如在beforeAll()
中,如果您需要等待请求或在请求完成后调用done()
,在本例中,因为您没有类似的操作,done()
是不必要的。顺便说一句,恭喜您找到了解决方案