如何防止角拦截器在茉莉花测试期间拾取$httpBackend响应

How to prevent angular interceptors from picking up $httpBackend responses during jasmine test

本文关键字:响应 httpBackend 测试 茉莉花 何防止      更新时间:2023-09-26

>我正在我的角度应用程序中为我的登录控制器编写测试,在"登录失败且凭据无效"测试期间,API 返回 401。问题是身份验证拦截器(其工作是拾取 401),干预并尝试执行未正确注入的依赖项。

以下是拦截器在我的应用程序中注入的方式.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@email.com', 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)

有什么建议吗?谢谢

看到这个答案。您需要用模拟的存储服务覆盖真实的存储服务:

  module(function ($provide) {
      $provide.value('storage', mockStorage);
  });