我想单独测试一个指令,将用户重定向到支持的社交登录网址.
因为Karma不支持全页重新加载,我想改变location.href JavaScript对象的行为,以将其接收的参数输出到具有特定ID的HTML元素,并且我遇到困难.
指示:
__app.directive('socialAuth',function(utils,authService,$location){ return{ restrict: 'A',scope: false,link: function(scope,elem,attrs){ elem.bind('click',function(){ utils.cleanSocialSearch(); if(attrs.checkBox == 'personal'){ scope.$apply(function(){ scope.model.personalShare[attrs.network] = true; $location.search('personalShare','1'); }); } else if(attrs.checkBox == 'group'){ scope.$apply(function(){ var __index = attrs.checkBox + '_' + attrs.network; scope.model.personalShare[__index] = true; $location.search('groupShare','1'); }); } var callback = encodeURIComponent(window.location.href); var loginUrl = utils.getBaseUrl() + '/social/login/' + attrs.network + '?success_url=' + callback; location.href = loginUrl; }); } } });
测试,试图模拟location.href对象(是的,我知道这不是一个功能):
var location = {//an attempt to mock the location href object href: function(param){ $('#content').html(param); } }; 'use strict'; describe('socail-auth',function(){//FB var scope,compiled,linkFn,html,elemPersonal,elemGroups,compile,authService; html = "<span id='content' data-social-auth data-network='facebook'>"; beforeEach(function(){ module('myApp.directives'); module('myApp.services'); inject(function($compile,$rootScope){ scope = $rootScope.$new(); linkFn = $compile(angular.element(html)); elem = linkFn(scope); scope.$digest(); elem.scope().$apply() }); }) it("should redirect user to social login url at the backend",function(){ // console.log(location.href); elem.click(); console.log($(elem).html()); expect($(elem).html()).toBeDefined(); }); });
解决方法
使用$window.location.href而不是location.href.
然后用空的对象模拟$window.location,它会做这个工作.
describe('location',function() { var $window; beforeEach( module('myApp') ); // You can copy/past this beforeEach beforeEach( module( function($provide) { $window = { // now,$window.location.path will update that empty object location: {},// we keep the reference to window.document document: window.document }; // We register our new $window instead of the old $provide.constant( '$window',$window ); })) // whatever you want to test it('should be redirected',function() { // action which reload the page $scope.reloadPage(); // we can test if the new path is correct. expect( $window.location.path ).toBe('/the-url-expected'); }) })