我想单独测试一个指令,将用户重定向到支持的社交登录网址.
因为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');
})
})