I'm writing tests for my login controller in my angular application, and during the "login fails with invalid credentials" test, the API returns a 401. The problem is the auth interceptor (whose job it is to pick up 401s), intervenes and tries to execute dependencies that haven't been correctly injected.
Here's how the interceptor is injected in my app.js:
$httpProvider.interceptors.push('authInterceptor');
And here's the guts of the interceptor (it's a factory):
return {
response: function(response){
return response || $q.when(response);
},
responseError: function(rejection) {
if (rejection.status === 401 && $location.path() !== '/login') {
// Clear user state.
delete $rootScope.loggedUser;
storage.clearAll();
document.cookie = "my_session=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
// Redirect.
$location.path("/login");
}
return $q.reject(rejection);
}
}
And here's my test (running against the login controller, not the above interceptor. Ideally the interceptor should never even execute in this test case):
it('should fail with invalid credentials', inject(function($httpBackend, $location, storage) {
$httpBackend.expectPOST('/api/login').respond(401);
scope.loginCredentials = {email : 'email@email.com', password : 'password'};
scope.login(scope.loginCredentials);
$httpBackend.flush();
}));
My mock of the storage library is injected like so-
var LoginCtrl,
mockStorage,
store,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope, storage, User) {
scope = $rootScope.$new();
store = [];
mockStorage = storage;
spyOn(mockStorage,'get').andCallFake(function(key){
return store[key];
});
spyOn(mockStorage,'set').andCallFake(function(key, val){
store[key] = val;
});
LoginCtrl = $controller('LoginCtrl', {
$scope: scope,
$rootScope: $rootScope,
storage: mockStorage,
User: User
});
}));
The problem is the mocked storage library in the test is not called by the interceptor, instead it attempts to inject the real one, unsuccessfully, causing an internal error in the library:
TypeError: Cannot read property 'clear' of undefined
at Object.publicMethods.clearAll (/path/to/app/ui/app/bower_components/ngStorage/src/angularLocalStorage.js:178:12)
Any suggestions? Thanks