Jasmine,使用 Promises 对 XMLHttpRequest 进行单元测试
Jasmine, Unit testing XMLHttpRequest with Promises
我有以下函数,它使用 Q promise 库
getConfig: function(params){
return this.codeApiClient.get(this.endpoints.config, params, {}).then(function(response){
return response;
}, function(err){
throw err;
});
}
上面的代码调用了下面显示的 API 代码(我已经缩写了代码以消除噪音)
CodeApiClient.prototype = {
get: function(endpoint, paramStr, headers){
var defer = new Q.defer();
var start_time = new Date().getTime();
var req = new XMLHttpRequest();
var url = endpoint + (paramStr.indexOf('?') !== -1 ? paramStr : '?' + paramStr);
req.open('GET', url);
req.onload = function() {
var request_time = new Date().getTime() - start_time;
// This is called even on 404 etc
if (req.status < 400) {
var response = JSON.parse(req.response)
response.__request_time = request_time;
defer.resolve(response);
} else {
// Otherwise reject with the status text
defer.reject(Error(req.statusText));
}
};
}
我的问题是:如何为 getConfig 编写 Jasmine 测试,即伪造响应并存根底层 XMLHttpRequest ?
sinon.js 有这个能力吗?我知道它可以在 $.ajax 上存根回调,但我不确定如何使用诸如 Q 之类的承诺库来执行此操作。注意这是纯 JavaScript,没有 angular 等
- 以下是如何在 jasmine 中使用 callFake 来 return 承诺。
- 现在由于 Q 和传统 jQuery 都提供延迟
对象,您可以将 $.Deferred() 替换为 Q.defer();
var tempObj = {
getConfig: function(params){
return this.codeApiClient.get(this.endpoints.config, params, {}).then(function(response){
return response;
}, function(err){
throw err;
});
}
codeApiClient : {
get : function(){
// some get function of codeApiClient
}
}
}
it('test getConfig success', function(){
var dummyResponse = {'someDummyKey' : 'someDummyValue'};
spyOn(tempObj.codeApiClient, 'get').and.callFake(function(e){
return $.Deferred().resolve(dummyResponse).promise();
});
tempObj.getConfig({});
//any expectations
});
it('test getConfig failure', function(){
var dummyResponse = {'error' : 'someDummyFailure'};
spyOn(tempObj.codeApiClient, 'get').and.callFake(function(e){
return $.Deferred().reject(dummyResponse).promise();
});
tempObj.getConfig({});
//any expectations
});
如果有人感兴趣,这是我的 Jasmine 测试,希望对您有所帮助
define([ 'q', 'lodash', 'jquery', 'ChatApi'], function (Q, _ , $ , ChatApi) {
describe('Chat Api test', function () {
var categories
var chatApi;
var fakeResponse;
beforeEach(function() {
//fakes
categories = {
"l10n": {
"defaultLanguage": "en-GB",
"languages": [
{
"name": "en-GB",
"value": "Tell me more..."
},
{
"name": "fr",
"value": "On veut tout savoir..."
},
{
"name": "de",
"value": "Wähle die passende Kategorie aus..."
}
]
}
};
fakeResponse = {
'categories': categories
}
chatApi = new ChatApi("https://server/gateway/","v1");
});
it('test getConfig success', function(done){
var getConfigCalled = spyOn(chatApi, 'getConfig').and.callFake(function(e){
//jQuery version of promises
//return $.Deferred().resolve(fakeResponse).promise();
var deferred = Q.defer();
deferred.resolve(fakeResponse);
return deferred.promise;
});
chatApi.getConfig({}).then(function(response){
//compare objects using lodash
var x = _.isEqual(response.categories, fakeResponse.categories);
expect(x).toBe(true);
})
expect(getConfigCalled).toHaveBeenCalled();
done();
});
});
});
我有以下函数,它使用 Q promise 库
getConfig: function(params){
return this.codeApiClient.get(this.endpoints.config, params, {}).then(function(response){
return response;
}, function(err){
throw err;
});
}
上面的代码调用了下面显示的 API 代码(我已经缩写了代码以消除噪音)
CodeApiClient.prototype = {
get: function(endpoint, paramStr, headers){
var defer = new Q.defer();
var start_time = new Date().getTime();
var req = new XMLHttpRequest();
var url = endpoint + (paramStr.indexOf('?') !== -1 ? paramStr : '?' + paramStr);
req.open('GET', url);
req.onload = function() {
var request_time = new Date().getTime() - start_time;
// This is called even on 404 etc
if (req.status < 400) {
var response = JSON.parse(req.response)
response.__request_time = request_time;
defer.resolve(response);
} else {
// Otherwise reject with the status text
defer.reject(Error(req.statusText));
}
};
}
我的问题是:如何为 getConfig 编写 Jasmine 测试,即伪造响应并存根底层 XMLHttpRequest ? sinon.js 有这个能力吗?我知道它可以在 $.ajax 上存根回调,但我不确定如何使用诸如 Q 之类的承诺库来执行此操作。注意这是纯 JavaScript,没有 angular 等
- 以下是如何在 jasmine 中使用 callFake 来 return 承诺。
- 现在由于 Q 和传统 jQuery 都提供延迟 对象,您可以将 $.Deferred() 替换为 Q.defer();
var tempObj = {
getConfig: function(params){
return this.codeApiClient.get(this.endpoints.config, params, {}).then(function(response){
return response;
}, function(err){
throw err;
});
}
codeApiClient : {
get : function(){
// some get function of codeApiClient
}
}
}
it('test getConfig success', function(){
var dummyResponse = {'someDummyKey' : 'someDummyValue'};
spyOn(tempObj.codeApiClient, 'get').and.callFake(function(e){
return $.Deferred().resolve(dummyResponse).promise();
});
tempObj.getConfig({});
//any expectations
});
it('test getConfig failure', function(){
var dummyResponse = {'error' : 'someDummyFailure'};
spyOn(tempObj.codeApiClient, 'get').and.callFake(function(e){
return $.Deferred().reject(dummyResponse).promise();
});
tempObj.getConfig({});
//any expectations
});
如果有人感兴趣,这是我的 Jasmine 测试,希望对您有所帮助
define([ 'q', 'lodash', 'jquery', 'ChatApi'], function (Q, _ , $ , ChatApi) {
describe('Chat Api test', function () {
var categories
var chatApi;
var fakeResponse;
beforeEach(function() {
//fakes
categories = {
"l10n": {
"defaultLanguage": "en-GB",
"languages": [
{
"name": "en-GB",
"value": "Tell me more..."
},
{
"name": "fr",
"value": "On veut tout savoir..."
},
{
"name": "de",
"value": "Wähle die passende Kategorie aus..."
}
]
}
};
fakeResponse = {
'categories': categories
}
chatApi = new ChatApi("https://server/gateway/","v1");
});
it('test getConfig success', function(done){
var getConfigCalled = spyOn(chatApi, 'getConfig').and.callFake(function(e){
//jQuery version of promises
//return $.Deferred().resolve(fakeResponse).promise();
var deferred = Q.defer();
deferred.resolve(fakeResponse);
return deferred.promise;
});
chatApi.getConfig({}).then(function(response){
//compare objects using lodash
var x = _.isEqual(response.categories, fakeResponse.categories);
expect(x).toBe(true);
})
expect(getConfigCalled).toHaveBeenCalled();
done();
});
});
});