Angular 1.1.5 служба на основе обещания на основе обещаний
Мы используем karma для unit test наших сервисов angular, эти службы содержат $http-звонки, поэтому мы имеем в виду $httpbackend, чтобы мы могли запускать приложение без сервера и db.
это прекрасно работает, служба может вызывать $http ( "someurl? id = 1234" ), и мы получаем правильные данные обратно.
Но когда мы пытаемся сделать то же самое в модульных тестах, мы не можем заставить его работать, обещание никогда не решает, когда оно связано с $http
Сервис:
getAllowedTypes: function (contentId) {
var deferred = $q.defer();
$http.get(getChildContentTypesUrl(contentId))
.success(function (data, status, headers, config) {
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for content id ' + contentId);
});
return deferred.promise;
}
Обманутый $httpbackend
$httpBackend
.whenGET(mocksUtills.urlRegex('/someurl'))
.respond(returnAllowedChildren); //returns a json object and httpstatus:200
Тест
it('should return a allowed content type collection given a document id', function(){
var collection;
contentTypeResource.getAllowedTypes(1234).then(function(result){
collection = result;
});
$rootScope.$digest();
expect(collection.length).toBe(3);
});
но коллекция undefined,.then() никогда не вызывается.
попробовал почти все, чтобы получить обещание разрешить $rootScope. $apply(), $digest, $httpBacke.flush(), но ничего не работает
Так издевается $httpBackend работает при вызове с контроллеров в приложении, но не тогда, когда услуги вызываются непосредственно в модульных тестах кармы
Ответы
Ответ 1
Вам не нужно дважды переваривать, так как $httpBackend.flush() вызывает переваривание.
Вы должны сделать вызов, вызвать дайджест, чтобы разрешить перехватчики запросов, сброс вызовов.
Вот рабочий Plnkr: http://plnkr.co/edit/FiYY1jT6dYrDhroRpFG1?p=preview
Ответ 2
В вашем случае вам нужно дважды переварить $, один раз для $httpBackend и снова для вашего собственного отложенного.
Итак:
it('should return a allowed content type collection given a document id', function(){
var collection;
contentTypeResource.getAllowedTypes(1234).then(function(result){
collection = result;
});
$httpBackend.flush();
$rootScope.$digest();
expect(collection.length).toBe(3);
});
Ответ 3
Ты почти там. В вашем случае вам просто нужно принудительно выполнить цикл дайджеста, прежде чем очистить HTTP-сервер. См. Пример кода ниже.
it('should return a allowed content type collection given a document id', function(){
var collection;
contentTypeResource.getAllowedTypes(1234).then(function(result){
collection = result;
});
$rootScope.$digest();
$httpBackend.flush();
expect(collection.length).toBe(3);
});