Ich versuche einen Angular Service mit Karma zu testen, und bekam ein paar seltsame Ergebnisse, also habe ich nur für den Hintern zwei Tests gemacht, die identisch waren um zu sehen, ob ich es bekommen würde die gleichen Ergebnisse, aber ich habe nicht:Testen von Angular Service im Karma: Selber Test, verschiedene Ergebnisse
describe('Profile Data Service', function() {
var LoginData, rootScope, $httpBackend;
beforeEach(module('myApp'));
describe('get profile data', function() {
beforeEach(inject(function(_LoginData_, $rootScope, _$httpBackend_) {
LoginData = _LoginData_;
LoginData.username= "jsmith";
LoginData.token = "token";
rootScope = $rootScope;
$httpBackend = _$httpBackend_;
}));
it('should get profile data on instantiation', inject(function(ProfileDataService) {
$httpBackend.expect('POST', 'http://mytestserver.com/api/', {
params: [{
username: "jsmith",
token: "token",
method: "getProfile"
}]
})
.respond({
result: {
address: "111 Main St."
city: "Los Angeles",
state: "CA"
}
});
$httpBackend.flush();
expect(ProfileDataService.profileData.address).toMatch("111 Main St.");
}));
it('should get profile data on instantiation', inject(function(ProfileDataService) {
$httpBackend.expect('POST', 'http://mytestserver.com/api/', {
params: [{
username: "jsmith",
token: "token",
method: "getProfile"
}]
})
.respond({
result: {
address: "111 Main St."
city: "Los Angeles",
state: "CA"
}
});
$httpBackend.flush();
expect(ProfileDataService.profileData.address).toMatch("111 Main St.");
}));
});
});
der erste Test bestanden, aber der zweite Test besagt, dass profileData nicht definiert ist. Sie sind identische Tests. Ich gehe davon aus, dass für jeden it
der ProfileDataService neu initialisiert wird, aber das ist möglicherweise nicht der Fall. Wenn das nicht der Fall ist, wie erstelle ich separate Tests, damit mein Service für jeden Testfall zerstört und neu initialisiert wird?
Die Logik für den Dienst ist recht einfach:
(function() {
'use strict';
angular.module('servicesModule')
.service('ProfileDataService', ProfileDataService);
ProfileDataService.$inject = ["$http", "$q", "LoginData", "CacheFactory"];
function ProfileDataService($http, $q, LoginData, CacheFactory) {
var ProfileDataService = this;
(function() {
init();
})();
function init() {
getProfile().then(function(profileData) {
ProileDataService.profileData = profileData;
});
}
function getProfile() {
var deferred = $q.defer();
var data = {
params: [{
username: LoginData.username,
token: LoginData.token,
method: "getProfile"
}]
};
var profileDataCache = CacheFactory.get('profileDataCache');
if (profileDataCache.get('profileData') && !invalidateCache) {
deferred.resolve(profileDataCache.get('profileData'));
}
else {
$http.post('http://mytestserver.com/api/', data)
.success(function(data) {
profileDataCache.put('profileData', response.result);
deferred.resolve(data.result);
});
}
return deferred.promise;
}
}
})();
ich auch darauf hingewiesen, dass ich rootScope.$digest()
an verschiedenen Orten im Test habe versuchte das Hinzufügen, aber das scheint keinen Unterschied zu machen. Ich dachte, manuell auslösen den Digest-Zyklus würde sicherstellen, dass der http-Post wurde gefangen und die Antwort verspottet.
Edit: Ich habe ein großes Detail weggelassen ... angular-cache
. Ich habe vergessen zu erwähnen, dass ich ein Cache-Plugin verwendet habe. Dies war der Grund für mein Problem. Nachdem ich einen Plünderer erschaffen hatte und feststellte, dass ich bei identischen Tests konstante Ergebnisse erzielte, wusste ich, dass etwas fehlte, was ich nicht realisieren konnte. Der zweite Test hat aufgrund meiner Caching-Logik keine POST-Anfrage gestellt.
Wie ist der Service definiert? –
'$ httpBackend.flush()' löst einen Digest aus, '$ digest()' ist redundant. Ja, für zwei identische Spezifikationen sollten die Ergebnisse identisch sein. Tests sind synchron und enthalten nichts, was den Status zwischen den Spezifikationen verlieren würde, daher ist die Ursache des Problems unbekannt. Eine Plunk/Geige, die das Problem repliziert, würde helfen. – estus