Reputation: 8663
I have a controller and service for which I have written some unit test. The service perform http
request, controller has .then
and .catch
block. I can test .then
block no problem, but how to test .catch
?
Controller:
$scope.performPost = function (action) {
$scope.shoppingCart = function() {
$scope.loading = true;
$scope.acText = '';
myService.postAction('cart', $scope.myData)
.then(function(data) {
$timeout(function(){
$scope.loading = false;
$scope.tick = true;
}, 1500);
})
.catch(function() {
$scope.errorException();
});
};
switch(action) {
case "viewShoppingCart":
$scope.shoppingCart();
break;
case "updateProfile":
$scope.updateUserDetails();
break;
}
};
Test for .then:
describe("MyController Tests", function() {
var scope;
var ctrl;
var customer = {
"accountId" : "12345678901",
"firstName" : "Joe",
"lastName" : "Bloggs",
};
var unlockRespone = {};
beforeEach(inject(function($rootScope, $controller, myService, _$q_, $httpBackend, $timeout) {
scope = $rootScope.$new();
rootScope = $rootScope;
mockMyService = myService;
pingUrl = "http://server:80/ping";
httpBackend = $httpBackend;
timeout = $timeout;
var unlockDeferred = _$q_.defer();
unlockDeferred.resolve(unlockRespone);
spyOn(mockMyService, 'postAction').and.returnValue(unlockDeferred.promise);
spyOn(rootScope, '$broadcast').and.callThrough();
ctrl = $controller('MyController', {$scope:scope, myService:mockMyService});
spyOn(scope, 'performPost').and.callThrough();
}));
it("Should call the viewShoppingCart function", function() {
httpBackend.expectGET(pingUrl).respond({ status: "OK" });
scope.performPost('viewShoppingCart');
timeout.flush(4000);
expect(scope.loading).toBeFalsy();
expect(scope.tick).toBeTruthy();
});
});
Upvotes: 0
Views: 5853
Reputation: 84
describe("MyController Tests", function() {
var scope;
var ctrl;
var $q;
var customer = {
"accountId" : "12345678901",
"firstName" : "Joe",
"lastName" : "Bloggs",
};
var response = {};
beforeEach(inject(function($rootScope, $controller, myService, _$q_, $httpBackend, $timeout) {
scope = $rootScope.$new();
rootScope = $rootScope;
mockMyService = myService;
pingUrl = "http://server:80/ping";
httpBackend = $httpBackend;
timeout = $timeout;
$q = _$q_;
spyOn(rootScope, '$broadcast').and.callThrough();
ctrl = $controller('MyController', {$scope:scope, myService:mockMyService});
spyOn(scope, 'performPost').and.callThrough();
}));
it("calls then", function() {
var deferred = $q.defer();
deferred.resolve(response);
spyOn(mockMyService, 'postAction').and.returnValue(deferred.promise);
// test code for then
});
it("calls catch", function() {
var deferred = $q.defer();
deferred.reject(response);
spyOn(mockMyService, 'postAction').and.returnValue(deferred.promise);
// test code for catch
});
});
Upvotes: 2
Reputation: 3426
You can pass 500 or other error status, to the respond method of $httpBackend as the first argument.
it("Should call errorException", function() {
spyOn(scope, 'errorException');
httpBackend.expectPOST('shopping-cart-url').respond(500, '');
scope.performPost('viewShoppingCart');
httpBackend.flush();
expect(scope.errorException).toHaveBeenCalled();
});
Upvotes: 1