Как я могу проверить угловое обещание с помощью ajax?
Код состоит в том, чтобы вызвать родителя через ajax, а затем вызвать остальную часть своих дочерних элементов через ajax.
Код,
app.controller('MyController', ['$scope', '$http', '$timeout', '$q', function($scope, $http, $timeout, $q) {
$scope.myParen = function(url) {
var deferred = $q.defer();
setTimeout(function() {
$http({
method: 'GET',
url: url
})
.success(function(data, status, headers, config) {
deferred.resolve([data]);
})
.error(function(data, status, headers, config) {
deferred.reject(data);
});
}, 1000);
return deferred.promise;
}
$scope.submit = function() {
$scope.commentCollection = '';
var promise = $scope.myParen('https://example.com/parents/1');
promise.then(function(success) {
var list = success;
$http({
method: 'GET',
url: 'https://example.com/parents/1/children'
})
.success(function(data, status, headers, config) {
$scope.commentCollection = list.concat(data);
})
.error(function(data, status, headers, config) {
$scope.error = data;
});
}, function(error) {
$scope.error = error;
});
};
}]);
Контрольная работа,
describe('MyController Test', function() {
beforeEach(module('RepoApp'));
var controller, $scope, $http, $httpBackend, $q;
var deferred;
beforeEach(inject(function ($rootScope, $controller, $http, $httpBackend, $q) {
$scope = $rootScope.$new();
deferred = $q.defer();
// Create the controller.
controller = $controller;
controller("MyController", {$scope, $http, $httpBackend, $q});
}));
it('should demonstrate using when (200 status)', inject(function($rootScope, $http, $httpBackend, $q) {
var $scope = {};
/* Code Under Test */
$scope.myParen = function(url) {
...
}
$scope.submit = function() {
...
};
/* End */
$scope.submit();
deferred.promise.then(function (value) {
$httpBackend.whenGET('https://example.com/parents/1/children', undefined, {})
.respond(function(){ return [200,{foo: 'bar'}]});
expect(value).toBe(4);
});
deferred.resolve(4);
$rootScope.$apply();
expect($scope.commentCollection).toEqual({foo: 'bar'});
}));
});
Неудачный результат,
Expected '' to equal { foo: 'bar' }.
Есть идеи?
Редактировать:
....
deferred.resolve(4);
$rootScope.$apply();
$timeout.flush();
expect($scope.commentCollection).toEqual({foo: 'bar'});
1) переключатель setTimeout
на $timeout
в контроллере
2) замените все $httpBackend
в функции beforeEach
3) использовать функции .flush()
describe('MyController Test', function() {
beforeEach(module('app'));
var controller, $scope, $http, httpBackend, $q;
var deferred;
beforeEach(inject(function ($rootScope, $controller, $http, $httpBackend, $q) {
$httpBackend
.whenGET('https://example.com/parents/1', undefined, {})
.respond(function(){ return [200, {parents: []}]});
$httpBackend
.whenGET('https://example.com/parents/1/children', undefined, {})
.respond(function(){ return [200, {foo: 'bar'}]});
$scope = $rootScope.$new();
deferred = $q.defer();
// Create the controller.
controller = $controller;
controller("MyController", {$scope: $scope, $http: $http, $httpBackend: $httpBackend, $q: $q});
}));
it('should demonstrate using when (200 status)', inject(function($httpBackend, $timeout) {
// var $scope = {}; // don't write it, becouse you rewrite a scope which defined at beforeEach function
$scope.submit();
//$httpBackend.flush(); // wait when backend return parents
$timeout.flush(); // wait timeout in $scope.myParen
$httpBackend.flush(); // wait when backend return children
expect($scope.commentCollection[0]).toEqual({parents: []});
expect($scope.commentCollection[1]).toEqual({foo: 'bar'});
}));
});
/* Code Under Test */
? это неправильно?
Error: No pending request to flush !
$scope.myParen
функцию $scope.myParen
чтобы использовать $timeout
вместо setTimeout
.
$scope.myParen = function(url) {
var promise = $http({
method: 'GET',
url: url
})
.then (function(response) {
var data = response.data;
return $timeout(function(){return data;}, 1000);
})
.catch(function(response) {
var data = response.data;
return
($timeout(angular.noop, 1000)
).then (function () {
throw data;
});
});
return promise;
}
Затем в тестах вы можете использовать $timeout.flush()
для синхронного сброса очереди отложенных функций.
Уведомление об изъятии
$ Http legacy обещает, что методы
success
иerror
устарели. Используйте стандарт,then
метод.- Ссылка на API-интерфейс AngularJS $ HTTP - уведомление об отказе
var deferred = $q.defer();
в этом?
$timeout
в свой контроллер, а затем не использовали его? ЗаменитеsetTimeout
на$timeout
.$timeout.flush()
чтобы синхронно очистить очередь отложенных функций.