我正在使用Ionic,我想在我的httpClient上进行单元测试
describe('send', function() {
var $httpBackend, userManager, apiClient;
beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
apiClient = new APIClient($httpBackend, userManager);
}));
it ('Should check if send() exists', function() {
expect(apiClient.send).toBeDefined();
});
it ('Should send GET request', function(done) {
var url = '/';
$httpBackend.expect('GET', url, {}, {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}).respond({});
apiClient.send({
url: url,
success: function(data, status) {
console.log(data);
console.log(status);
done();
},
error: function(data, status) {
console.log(data);
console.log(status);
done();
}
});
});
});
但我一直有这个错误
Error: Unexpected request: [object Object] undefined
Expected GET /
我在投入角度模拟之前添加console.log
,我有
LOG: Object{method: 'GET', url: '/', headers: Object{Content-Type: 'application/x-www-form-urlencoded; charset=UTF-8'}, data: Object{}}
我也只尝试$httpBackend.expect('GET', url)
并且我有dame错误
我尝试了$httpBackend.when('GET', url)
,我有
Error: Unexpected request: [object Object] undefined
No more request expected
以下是APIClient的完整代码:
/**
* Util
*
* @constructor
*/
var APIClient = function($http, UserManager)
{
this.userManager = UserManager;
this.tokenUrl = AppSettings.baseApiUrl + '/oauth/v2/token';
this.clientId = AppSettings.clientId;
this.clientSecret = AppSettings.clientSecret;
this.accessTokenKey = 'access_token';
this.refreshTokenKey = 'refresh_token';
this.expireTokenKey = 'expires_in';
var that = this;
/**
*
* @param {{method:{string}, url:{string}, headers:{}, data:{}, success:function({}, int), error:function({}, int), oauth:{boolean}}} customerData
*/
this.send = function(customerData)
{
var data = {
method: 'GET',
url: null,
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
data: {},
file: null,
success: function(){},
error: function(){},
oauth: false
};
for (var attrName in customerData) {
if (customerData.hasOwnProperty(attrName)) {
data[attrName] = customerData[attrName];
}
}
var successCallback = data.success;
var errorCallback = data.error;
var oAuthStatus = 1;
if (data.oauth) {
oAuthStatus = 0;
this.getToken(function(success, message){
if (success) {
data.url = that.setGetParameter(
data.url,
that.accessTokenKey,
message
);
oAuthStatus = 1;
} else {
errorCallback(message);
oAuthStatus = 2;
}
});
}
var intvl = setInterval(function() {
if (oAuthStatus != 0) {
clearInterval(intvl);
if (oAuthStatus == 1) {
if (data.file !== null) {
sendFile(data, successCallback, errorCallback);
} else {
var tmpData = '';
for (var key in data.data) {
if (data.data.hasOwnProperty(key)) {
data.url = that.setGetParameter(data.url, key, data.data[key]);
}
}
if (data.method !== 'GET') {
data.data = tmpData.substring(1);
} else {
data.data = {};
}
sendRequest(data, successCallback, errorCallback);
}
}
}
}, 100);
};
/**
*
* @param {function(boolean, {})} callback
*/
this.getToken = function(callback)
{
if (!this.isToken()) {
this.loadToken(function(success, data){
if (success) {
callback(true, that.getAccessToken());
} else {
callback(false, data);
}
});
}else if (this.isTokenExpired()) {
this.refreshToken(function(success, data){
if (success) {
callback(true, this.getAccessToken());
} else {
callback(false, data);
}
});
} else {
callback(true, this.getAccessToken());
}
};
/**
*
* @param {function(boolean, data)} callback
*/
this.loadToken = function(callback)
{
if (!this.userManager.isCurrent()) {
throw {
key: 'api_client_user_not_found',
message: 'User not found'
}
}
var user = this.userManager.getCurrent();
this.send({
method: 'GET',
url: this.tokenUrl,
data: {
client_id: this.clientId,
client_secret: this.clientSecret,
username: user.getUsername(),
password: user.getPassword(),
grant_type: 'password'
},
success: function (data) {
that.updateToken(data);
callback(true, data);
},
error: function (data) {
callback(false, data)
}
});
};
/**
*
* @param {function(boolean, {})} callback
*/
this.refreshToken = function(callback)
{
if (!this.userManager.isCurrent()) {
throw {
key: 'api_client_user_not_found',
message: 'User not found'
}
}
this.send({
method: 'GET',
url: this.tokenUrl,
data: {
client_id: this.clientId,
client_secret: this.clientSecret,
refresh_token: this.getRefreshToken(),
grant_type: 'refresh_token'
},
success: function (data) {
that.updateToken(data);
callback(true, data)
},
error: function (data) {
callback(false, data)
}
});
};
/**
*
* @param {{access_token:{string}, refresh_token:{string}, expires_in:{string}}} data
*/
this.updateToken = function(data)
{
window.localStorage.setItem(this.accessTokenKey, data[this.accessTokenKey]);
window.localStorage.setItem(this.refreshTokenKey, data[this.refreshTokenKey]);
var t = new Date();
t.setSeconds(t.getSeconds() + data[this.expireTokenKey]);
window.localStorage.setItem(this.expireTokenKey, t.getTime());
};
/**
* Clear api tokens
*/
this.clearToken = function()
{
window.localStorage.removeItem(this.accessTokenKey);
window.localStorage.removeItem(this.refreshTokenKey);
window.localStorage.removeItem(this.expireTokenKey);
};
/**
*
* @returns string
*/
this.getAccessToken = function()
{
return window.localStorage.getItem(this.accessTokenKey);
};
/**
*
* @returns string
*/
this.getRefreshToken = function()
{
return window.localStorage.getItem(this.refreshToken);
};
/**
*
* @returns string
*/
this.getTokenExpiration = function()
{
return window.localStorage.getItem(this.expireTokenKey);
};
/**
*
* @returns {boolean}
*/
this.isToken = function()
{
return null !== this.getAccessToken();
};
/**
*
* @returns {boolean}
*/
this.isTokenExpired = function()
{
var t = new Date;
return t.getTime() > this.getTokenExpiration()
};
/**
*
* @param {string} url
* @param {string} paramName
* @param {string} paramValue
* @returns {string}
*/
this.setGetParameter = function(url, paramName, paramValue)
{
if (url.indexOf(paramName + "=") >= 0)
{
var prefix = url.substring(0, url.indexOf(paramName));
var suffix = url.substring(url.indexOf(paramName));
suffix = suffix.substring(suffix.indexOf("=") + 1);
suffix = (suffix.indexOf("&") >= 0) ? suffix.substring(suffix.indexOf("&")) : "";
url = prefix + paramName + "=" + paramValue + suffix;
}
else
{
if (url.indexOf("?") < 0)
url += "?" + paramName + "=" + paramValue;
else
url += "&" + paramName + "=" + paramValue;
}
return url;
};
function sendRequest(data, successCallback, errorCallback) {
$http({
method: data.method,
url: data.url,
headers: data.headers,
data: data.data
}).success(function(data, status){
successCallback(data, status);
}).error(function(data, status){
errorCallback(data, status);
});
}
function sendFile(data, successCallback, errorCallback) {
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName="file";
options.params = data.data;
var ft = new FileTransfer();
ft.upload(data.file, data.url, uploadSuccess, uploadError, options);
function uploadSuccess(r) {
result = JSON.parse(r.response);
successCallback(result, true);
}
function uploadError(error) {
errorCallback(error, true)
}
}
};
angular.module('api.client', []).factory('APIClient', ['$http', 'UserManager', function($http, UserManager)
{
var client = new APIClient($http, UserManager);
return {
send: function(data)
{
return client.send(data);
},
clearToken: function()
{
client.clearToken();
}
}
}]);
答案 0 :(得分:1)
您的错误发生是因为您需要查询$ http(&#39; GET&#39;,&#39; /&#39;) 永远不会发生!
我不确定如何管理您传递$http
依赖项参数的情况。
$ httpBackend单独管理$ http调用的替换,因此期望代码中有$ http。
为了保持您的代码原样,我将$ http注入您的beforeEach,但我从未测试过。
beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
var $http = $injector.get('$http');
apiClient = new APIClient($http, userManager);
}));
我宁愿修改我的APIClient而不接受$ http参数,因此angularJS $ httpBackend的标准机制会适用
此外,请不要忘记使用:$httpBackend.flush()
使用经过培训的回复来刷新所有待处理的请求。