我试图测试我的响应拦截器,但是我很难弄清楚如何模拟$window对象.这是我的拦截器代码:
'use strict'; angular.module('Domain.handlers') .config(function($httpProvider) { $httpProvider.responseInterceptors.push('UnauthorizedInterceptor'); }) .factory('UnauthorizedInterceptor',function($q,$injector,$window,ENV) { return function(promise) { var success = function(response) { return response; }; var error = function(response) { if (response.status === 401) { $window.location.href = ENV.account + '/oauth/authorize?client_id=' + ENV.clientId + '&redirect_uri=' + ENV.app + '/oauth/callback&response_type=token'; } return $q.reject(response); }; return promise.then(success,error); }; });
这里是我的规格:
'use strict'; describe('Domain.handlers.response',function() { var UnauthorizedInterceptor,httpProvider,$httpBackend,$http,token = '123456789'; beforeEach(module('Domain.handlers',function($httpProvider) { httpProvider = $httpProvider; })); beforeEach(inject(function(_UnauthorizedInterceptor_,_$httpBackend_,_$http_) { UnauthorizedInterceptor = _UnauthorizedInterceptor_; $httpBackend = _$httpBackend_; $http = _$http_; })); describe('UnauthorizedInterceptor',function() { it('should be defined',function() { expect(UnauthorizedInterceptor).toBeDefined(); }); describe('HTTP status',function() { describe('is 200 OK',function() { it('should return a 200 status',function() { $httpBackend.expectGET('http://api.domain.com/clients').respond(200,{}); $http.get('http://api.domain.com/clients'); $httpBackend.flush(); }); }); describe('is 401 Unauthorized',function() { it('should redirect to accounts.domain.com',inject(function($window) { $httpBackend.expectGET('http://api.domain.com/clients').respond(401,{}); $http.get('http://api.domain.com/clients'); expect($window.location.href).toEqual('http://accounts.domain.com/oauth/.....'); $httpBackend.flush(); })); }); }); }); });
我有一个:预期’http:// localhost:8080 / context.html’等于’http://accounts.domain.com/oauth / …..’.任何帮助如何正确地模拟$window对象或更一般如何测试401重定向的情况?
您应该使用
more recent syntax构建拦截器定义.您的URL构造也应该在一个服务中,以便容易地在测试中被嘲笑.
.factory('UnauthorizedInterceptor',OtherService) { var service = { responseError: handleUnauthorized }; return service; function handleUnauthorized(rejection) { if (rejection.status === 401) { $window.location.href = OtherService.getUnauthorizedRedirectURL(); } return $q.reject(rejection); } });
这样做可以像任何其他工厂一样测试它,而不用担心$http拦截器的内部实现,或者必须用$httpBackend来模拟响应.
describe('Domain.handlers.response',function() { var $window,UnauthorizedInterceptor,OtherService,redirectUrl = 'someUrl'; beforeEach(module('Domain.handlers')); beforeEach(function () { $window = { location: { href: null } }; module(function($provide) { $provide.value('$window',$window); }); }); beforeEach(inject(function(_UnauthorizedInterceptor_,_OtherService_) { UnauthorizedInterceptor = _UnauthorizedInterceptor_; OtherService = _OtherService_; spyOn(OtherService,'getUnauthorizedRedirectURL').andReturn(redirectUrl); })); describe('UnauthorizedInterceptor',function() { expect(UnauthorizedInterceptor).toBeDefined(); }); it('should have a handler for responseError',function () { expect(angular.isFunction(UnauthorizedInterceptor.responseError)).toBe(true); }); describe('when HTTP 401',function () { beforeEach(function () { var rejection = { status: 401 }; UnauthorizedInterceptor.responseError(rejection); }); it('should set window location',function () { expect($window.location.href).toBe(redirectUrl); }); }); describe('when not HTTP 401',function () { beforeEach(function () { var rejection = { status: 500 }; UnauthorizedInterceptor.responseError(rejection); }); it('should not set window location',function () { expect($window.location.href).not.toBe(redirectUrl); }); }); }); });