admin管理员组文章数量:1428488
I have the following controller:
angular.module('app').controller('userList'
, ['$scope','appRules',function ($scope,appRules) {
$scope.isUserInRole=function(user,role){
console.log("exucuting userIsInRole:",user,role);//never happens
return appRules.userIsInRole(user,role);
}
window.sscope=$scope;
console.log($scope.menu);
}]);
This is used for the following route:
angular.module('app', [,'ui.bootstrap','ngRoute'])
.config(['$routeProvider','$locationProvider'
,function($routeProvider,$locationProvider){
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
$routeProvider
.when('/admin/users',{
templateUrl:'app/js/partials/admin/users/list.html',
controller:'userList'
});
}]);
The template would have something that will check if user can see this page or not (even if someone hacks javascript it doesn't matter because when data is fetched or submitted the server checks as well).
<div data-ng-if="!isUserInRole(login.user,'Administrator')" class="red">
Please log in or log in as another user.
</div>
<div data-ng-if="isUserInRole(login.user,'Administrator')" class="green">
Page to edit users.
</div>
Now I would like to create a controller in my test and see when it renders if it renders correctly:
var controller,scope,element;
beforeEach(inject(function($controller
,$rootScope,$pile,appRules) {
scope=$rootScope;
scope.login={};
scope.isUserInRole=appRules.userIsInRole;
controller = $controller('userList',{
$scope:scope
});
//here I have the controller but how to get the html it generates
// when rendering the template?
element = $pile("<div ng-controller='userList'>"
+"<div data-ng-view=''></div></div>")(scope);
//here element isn't rendered at all, works on directives but how
// to do this with controllers?
console.log("element is:",element);
}));
I would like to write a test like
it('Check page won\'t show if user is not set or is not Administrator.'
, function() {
expect($(element).text().trim()
.indexOf("Please log in or log in as another user."))
.toBe(0,'Show login message when login.user is not set.');
});
Not sure how to get element though.
[update]
I'm actually trying to test a template, because this is used by a controller I was thinking testing it with a controller but as Jon suggested it can just be loaded as template.
How to make it pile and manipulate scope and pile again I don't know. The following:
var el = angular.element(
$templateCache
.get('app/js/partials/admin/users/list.html'));
$rootScope = _$rootScope_;
$rootScope.menu={login:{}};
el.scope($rootScope);
$rootScope.$apply();
console.log(el.text());
This gives me the output of both Please log in or log in as another user.
and Page to edit users.
Looks like element is just the raw element not piled one.
Trying something like this doesn't do much either:
beforeEach(inject(function(_$pile_
, _$rootScope_,appSettings,$templateCache){
console.log("before each");
var el = angular.element($templateCache
.get('app/js/partials/admin/users/list.html'));
var pile=_$pile_;
var $rootScope=_$rootScope_;
$rootScope.login:{};
$rootScope.isUserInRole=appSettings.userIsInRole;
//I would think that pile would invoke the ng-if and appSettings.userIsInRole
// but no console log in that function is shown.
var element = pile($templateCache
.get('app/js/partials/admin/users/list.html'))($rootScope);
console.log("element is:",element.html());//=undefined
}));
I have the following controller:
angular.module('app').controller('userList'
, ['$scope','appRules',function ($scope,appRules) {
$scope.isUserInRole=function(user,role){
console.log("exucuting userIsInRole:",user,role);//never happens
return appRules.userIsInRole(user,role);
}
window.sscope=$scope;
console.log($scope.menu);
}]);
This is used for the following route:
angular.module('app', [,'ui.bootstrap','ngRoute'])
.config(['$routeProvider','$locationProvider'
,function($routeProvider,$locationProvider){
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
$routeProvider
.when('/admin/users',{
templateUrl:'app/js/partials/admin/users/list.html',
controller:'userList'
});
}]);
The template would have something that will check if user can see this page or not (even if someone hacks javascript it doesn't matter because when data is fetched or submitted the server checks as well).
<div data-ng-if="!isUserInRole(login.user,'Administrator')" class="red">
Please log in or log in as another user.
</div>
<div data-ng-if="isUserInRole(login.user,'Administrator')" class="green">
Page to edit users.
</div>
Now I would like to create a controller in my test and see when it renders if it renders correctly:
var controller,scope,element;
beforeEach(inject(function($controller
,$rootScope,$pile,appRules) {
scope=$rootScope;
scope.login={};
scope.isUserInRole=appRules.userIsInRole;
controller = $controller('userList',{
$scope:scope
});
//here I have the controller but how to get the html it generates
// when rendering the template?
element = $pile("<div ng-controller='userList'>"
+"<div data-ng-view=''></div></div>")(scope);
//here element isn't rendered at all, works on directives but how
// to do this with controllers?
console.log("element is:",element);
}));
I would like to write a test like
it('Check page won\'t show if user is not set or is not Administrator.'
, function() {
expect($(element).text().trim()
.indexOf("Please log in or log in as another user."))
.toBe(0,'Show login message when login.user is not set.');
});
Not sure how to get element though.
[update]
I'm actually trying to test a template, because this is used by a controller I was thinking testing it with a controller but as Jon suggested it can just be loaded as template.
How to make it pile and manipulate scope and pile again I don't know. The following:
var el = angular.element(
$templateCache
.get('app/js/partials/admin/users/list.html'));
$rootScope = _$rootScope_;
$rootScope.menu={login:{}};
el.scope($rootScope);
$rootScope.$apply();
console.log(el.text());
This gives me the output of both Please log in or log in as another user.
and Page to edit users.
Looks like element is just the raw element not piled one.
Trying something like this doesn't do much either:
beforeEach(inject(function(_$pile_
, _$rootScope_,appSettings,$templateCache){
console.log("before each");
var el = angular.element($templateCache
.get('app/js/partials/admin/users/list.html'));
var pile=_$pile_;
var $rootScope=_$rootScope_;
$rootScope.login:{};
$rootScope.isUserInRole=appSettings.userIsInRole;
//I would think that pile would invoke the ng-if and appSettings.userIsInRole
// but no console log in that function is shown.
var element = pile($templateCache
.get('app/js/partials/admin/users/list.html'))($rootScope);
console.log("element is:",element.html());//=undefined
}));
Share
Improve this question
edited Jul 19, 2014 at 7:56
HMR
asked Jul 19, 2014 at 6:46
HMRHMR
39.4k25 gold badges98 silver badges174 bronze badges
4
- A controllers scope is isolated so unless your userList controller is applied to an html element that encapsulates all other this will not work as a scalable solution as it requires lots of nested scopes which increase memory. I've written a blog post about user security in angular which is a better, more scalable approach - jonsamwell./url-route-authorization-and-security-in-angular – Jon Commented Jul 19, 2014 at 6:53
- @JonSamwell Thank you for your reply. In general; if I want to check if a loading image is shown when the route/controller is used because somewhere else a directive needs to fetch some data and then want to see if this is gone when fetching data is fetched/resolved how would I go about testing that? I can mock http service promises and see how a directive renders but this is a controller that's used on certain routes. Have not been able to find any working code to test this. – HMR Commented Jul 19, 2014 at 7:16
- This sounds a bit more like an intergration test issue. Unit test should test isolation so you should test that the thing that loads the image is triggered on http calls via a route interceptor then you should have separates tests to test the thing that actually does the dom manipulation to put the image on the screen - maybe ask a separate question for that one. – Jon Commented Jul 19, 2014 at 7:19
- @JonSamwell I would like to test the template to display one thing when scope.login.loading is true, another when scope.login.loading is false and scope.login.user is truethy and yet another thing when scope.login.user is true. Since the template is used by a controller I thought I add the test in the controller but could as well just leave the controller out of it if there is a way to pile the template with different scopes. The part that changes the scope is covered in another unit test but I want to make sure the template behaves correctly. – HMR Commented Jul 19, 2014 at 7:40
2 Answers
Reset to default 3Add your templates to the cache using ng-templates or ng-html2js so they are available when Karma runs. Then do this:
var scope = null;
beforeEach(inject(function($templateCache,_$pile_,_$rootScope_, _$controller_) {
//get the template from the cache
template = $templateCache.get('src/main/app/ponents/someController/widget-search.tpl.html');
$pile = _$pile_;
$rootScope = _$rootScope_;
$controller = _$controller_;
scope = $rootScope.new();
//pile it
element = $pile(template)(scope);
}));
//then shove your piled element into your controller instance
it( 'should be instantiated since it does not do much yet', function(){
ctrl = $controller('SomeController',
{
$scope: scope,
$element: element
});
scope.$digest();
// my controller should set a variable called hasInstance to true when it initializes. Here i'm testing that it does.
expect( ctrl.hasInstance).toBeTruthy();
});
For more info, see http://angular-tips./blog/2014/06/introduction-to-unit-test-directives/
If you are using Karma you could use the ng-html2js karma pre processor which basically runs through your templates and turns them into module which you can include in your test which populate the $templateCache so your template is available.
本文标签: javascriptGet compiled template for controller in unit testStack Overflow
版权声明:本文标题:javascript - Get compiled template for controller in unit test - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745525527a2661818.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论