我的問題:在Karma中,我在測試實際服務時嘲笑注入服務。模擬的服務獲取一些數據,併發回一個承諾。我無法弄清楚我做錯了什麼。承諾在被測服務中使用模擬服務解決
我知道實際的「登錄」機制存在一些問題,但我用它來說明這個Karma問題。我不打算將它用作生產代碼。 (然而,爲了更好地說明這個問題的任何建議,歡迎!)
首先,我在一個通用的.js文件寫到這,並說:「節點testcode.js」
testcode.js:
function Login(name,password,callback){
setTimeout(function(){
var response;
var promise = getByUserName();
promise.then(successCb);
function successCb(userObj){
if (userObj != null && userObj.password === password) {
response = { success : true };
} else {
response = { success: false, message: 'Username or password is incorrect' };
}
callback(response);
};
},200);
}
function getByUserName(){
return Promise.resolve(user);
}
var user = {
username : 'test',
id : 'testId',
password : 'test'
};
var test = undefined;
Login(user.username,user.password,testCb);
function testCb(response){
test = response;
console.log("Final: " + JSON.stringify(test));
}
這給了我,我的預期結果:
Final: {"success":true}
現在,我嘗試在噶重複這個...
TestService的:
(function(){
"use strict";
angular.module('TestModule').service('TestService',TestService);
TestService.$inject = ['$http','$cookieStore','$rootScope','$timeout','RealService'];
})();
function TestService($http,$cookieStore,$rootScope,$timeout,RealService){
var service = {};
service.Login = Login;
/* more stuff */
return service;
function Login(username,password,callback){
$timeout(function() {
var response;
var promise = UserService.GetByUsername(username);
promise.then(successCb);
function successCb(user){
if (user !== null && user.password === password) {
response = { success: true };
} else {
response = { success: false, message: 'Username or password is incorrect' };
}
callback(response);
};
}, 1000);
}
}
我噶茉莉花測試:
describe('TestModule',function(){
beforeEach(module('TestModule'));
describe('TestService',function(){
var service,$rootScope,
user = {
username : 'test',
id : 'testId',
password : 'test'
};
function MockService() {
return {
GetByUsername : function() {
return Promise.resolve(user);
}
};
};
beforeEach(function(){
module(function($provide){
$provide.service('RealService',MockService);
});
inject(['$rootScope','TestService',
function($rs,ts){
$rootScope = $rs;
service = ts;
}]);
});
/**
* ERROR: To the best of my knowledge, this should not pass
*/
it('should Login',function(){
expect(service).toBeDefined();
var answer = {"success":true};
service.Login(user.username,user.password,testCb);
//$rootScope.$apply(); <-- DID NOTHING -->
//$rootScope.$digest(); <-- DID NOTHING -->
function testCb(response){
console.log("I'm never called");
expect(response.success).toBe(false);
expect(true).toBe(false);
};
});
});
});
爲什麼承諾沒有得到解決?我已經試過用$ rootScope。$ digest()基於類似的問題閱讀過,但似乎沒有得到testCb被調用。
你在哪裏調用'$ rootScope。$ digest()'?它不在代碼中。是否有一個真正的原因,爲什麼承諾鏈被回調污染? 'getByUserName'是否由於意圖或錯誤而返回本地許諾而不是'$ q'? – estus
$ rootScope。$ digest() - 我把它放在各個地方的代碼中,但它對結果從來沒有任何影響。所以,我現在沒有在那裏。坦率地說,我不知道如何使用它。 getByUsername返回本地承諾的意圖。坦率地說,我真的不知道如何使用$ q。看完這篇文章後,http://www.codelord。net/2015/09/24/$ q-dot-defer-youre-doing-it-wrong /,我只是舉起雙手,想着又一天節省$ q。 – westandy
我已經在JS工作了兩年,Angular已經工作了6個月。我覺得我已經有了基礎知識,但是像$ digest和$ q這樣的東西已經教會了我,否則。因果報應和單位測試指令幾乎壓垮了我的靈魂(參見我的其他關於業力指令的問題)。 – westandy