Reputation: 1801
I have a controller with one function exposed in the $scope that calls a service, loginService
$scope.validateCredentials = function (callback){
loginService.validate($scope.username, $scope.password)
.then(function (){
self.credentialsRight();
if (typeof callback !== "undefined") {
callback("credentials right callback");
}
}, function (){
self.credentialsWrong();
if (typeof callback !== "undefined") {
callback("credentials wrong callback");
}
})
}
I have managed to test if the beforementioned method works right testing it with jasmine like this
it("validateCredentials - passing in the right credentials", function() {
spyOn(loginService, 'validate').andCallFake(function() {
return successfulDeferred.promise;
});
$scope.validateCredentials(function() {
expect($scope.error).toBe(false);
});
$scope.$apply();
});
The reason why I call andCallFake using an spy is because I want to fake a promise being returned. Please note I have tried to do this using $httpBackend.onPOST unsusccefully.
However, I feel that the usage of a callback in my controller only for testing purposes and deal with an async response is weird. Do you guys know a better way to implement it? I have seen waitsFor and runs but doesn't seem to work for me.
Upvotes: 2
Views: 935
Reputation: 1830
Here is a similar test that I have in my code base. You will need to adapt for your solution. But basically you need to call deferred.reject(someData) after you call the service method. Then you may need to call a digest on the root scope. Then test your expectation. Replace personApi with your loginService.
//setup the controller
var $scope, ctrl, deferred, personApi, rootScope, log,basePerson;
beforeEach(inject(function ($rootScope, $q, $controller, _personApi_) {
rootScope = $rootScope;
$scope = $rootScope.$new();
deferred = $q.defer();
personApi = _personApi_;
ctrl = $controller('personCtrl', {
$scope: $scope,
personApi: personApi
});
}));
it('should map returned errors to the original object', function () {
spyOn(personApi, 'save').and.callFake(function () {
return deferred.promise;
});
$scope.person = basePerson;
deferred.reject(stronglyNamedErrors);
$scope.savePerson();
$scope.$root.$digest();
expect($scope.person.firstNameError).toBe(stronglyNamedErrors.firstNameError);
});
Upvotes: 1