Как запретить угловым перехватчикам получать ответы $httpBackend во время теста jasmine

Я пишу тесты для моего контроллера входа в мое приложение angular, и во время теста «сбой входа с неверными учетными данными» API возвращает 401. Проблема заключается в перехватчике аутентификации (чья работа заключается в том, чтобы собирать 401), вмешивается и пытается выполнить зависимости, которые не были правильно внедрены.

Вот как перехватчик внедряется в мой app.js:

$httpProvider.interceptors.push('authInterceptor');

А вот и кишки перехватчика (это заводской):

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);
    }
}

И вот мой тест (работает с контроллером входа в систему, а не с указанным выше перехватчиком. В идеале перехватчик никогда не должен даже выполняться в этом тестовом примере):

it('should fail with invalid credentials', inject(function($httpBackend, $location, storage) {
    $httpBackend.expectPOST('/api/login').respond(401);
    scope.loginCredentials = {email : '[email protected]', password : 'password'};
    scope.login(scope.loginCredentials);
    $httpBackend.flush();
}));

Мой макет библиотеки хранения вводится так:

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
    });
}));

Проблема в том, что фиктивная библиотека хранилища в тесте не вызывается перехватчиком, вместо этого он безуспешно пытается внедрить настоящую, что вызывает внутреннюю ошибку в библиотеке:

TypeError: Cannot read property 'clear' of undefined
    at Object.publicMethods.clearAll (/path/to/app/ui/app/bower_components/ngStorage/src/angularLocalStorage.js:178:12)

Какие-либо предложения? Спасибо


person Dan Sunderland    schedule 13.01.2015    source источник
comment
Как вы пытаетесь внедрить фиктивное хранилище? Можете ли вы также разместить этот фрагмент кода?   -  person Thiago Felix    schedule 13.01.2015


Ответы (1)


См. этот ответ. Вам нужно будет переопределить реальную службу хранения вашей издевательской:

  module(function ($provide) {
      $provide.value('storage', mockStorage);
  });
person noj    schedule 14.01.2015
comment
Вот и получилось, большое спасибо. Пришлось макетировать библиотеку хранения немного глубже, но я добавил, что перед каждым тестом и перехватчик корректно использовал mock-версию. - person Dan Sunderland; 14.01.2015
comment
У меня тоже сработало, но я не понимаю почему. Если хранилище в данном случае является фабрикой, то не должно ли это быть $provide.factory('storage', mockStorage)? - person Mari; 16.07.2015
comment
Нет, потому что mockStorage — это возвращаемое значение исходной фабрики, а не самой фабрики. $provide.factory ожидает, что функция с возвращаемым значением будет использоваться в качестве введенного значения. Вы можете увидеть здесь, как значение оборачивает функцию, используя valuefn в возврате утверждение. Надеюсь, это имеет смысл. - person noj; 17.07.2015