Is it possible to test an angular promise that includes ajax calls?
The scenario involves making an ajax call to a parent, followed by additional ajax calls to its children.
Here is the code snippet:
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;
});
};
}]);
A test case for MyController:
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'});
}));
});
Failed result,
Expected '' to equal { foo: 'bar' }.
Any suggestions on how to improve this test case?
Edit:
....
deferred.resolve(4);
$rootScope.$apply();
$timeout.flush();
expect($scope.commentCollection).toEqual({foo: 'bar'});