如何用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'});
答案 0 :(得分:2)
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'});
}));
});
答案 1 :(得分:1)
重新编写$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遗留承诺方法
success
和error
已被弃用。改为使用标准then
方法。- AngularJS $http Service API Reference -- deprecation notice