在单元测试中获取控制器的编译模板
Get compiled template for controller in unit test
我有以下控制器:
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);
}]);
用于以下路由:
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'
});
}]);
模板将有一些东西,将检查用户是否可以看到这个页面或不(即使有人破解javascript没关系,因为当数据被获取或提交服务器检查)。
<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>
现在我想在我的测试中创建一个控制器,看看它何时呈现,如果它正确呈现:
var controller,scope,element;
beforeEach(inject(function($controller
,$rootScope,$compile,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 = $compile("<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);
}));
我想写一个像
这样的测试 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.');
});
不知道如何获取元素。
(更新)我实际上是在测试一个模板,因为这是由一个控制器使用的,我想用一个控制器测试它,但正如Jon建议的那样,它可以只是作为模板加载。
如何使它编译和操纵作用域并再次编译我不知道。如下:
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());
这给了我Please log in or log in as another user.
和Page to edit users.
的输出,看起来元素只是原始元素而不是编译的元素。
尝试这样做也没有多大作用:
beforeEach(inject(function(_$compile_
, _$rootScope_,appSettings,$templateCache){
console.log("before each");
var el = angular.element($templateCache
.get('app/js/partials/admin/users/list.html'));
var compile=_$compile_;
var $rootScope=_$rootScope_;
$rootScope.login:{};
$rootScope.isUserInRole=appSettings.userIsInRole;
//I would think that compile would invoke the ng-if and appSettings.userIsInRole
// but no console log in that function is shown.
var element = compile($templateCache
.get('app/js/partials/admin/users/list.html'))($rootScope);
console.log("element is:",element.html());//=undefined
}));
使用ng-templates或ng-html2js将模板添加到缓存中,以便在Karma运行时可用。然后这样做:
var scope = null;beforeEach(inject(function($templateCache,_$compile_,_$rootScope_, _$controller_) {
//get the template from the cache
template = $templateCache.get('src/main/app/components/someController/widget-search.tpl.html');
$compile = _$compile_;
$rootScope = _$rootScope_;
$controller = _$controller_;
scope = $rootScope.new();
//compile it
element = $compile(template)(scope);
}));
//then shove your compiled 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();
});
更多信息请参见http://angular-tips.com/blog/2014/06/introduction-to-unit-test-directives/
如果你正在使用Karma,你可以使用ng-html2js Karma预处理器,它基本上运行你的模板,并把它们变成模块,你可以包括在你的测试中,填充$templateCache,所以你的模板是可用的。
相关文章:
- 在指令控制器中使用$attrs时出现问题
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 从控制器返回后Ajax启动事件激发
- 获取@ResponseBody的一部分作为主干和Spring MVC控制器之间的参数
- 如何在单击复选框后调用控制器方法
- 在控制器和数据对象之间同步数据
- 将Javascript数组发送到控制器ASP.NET MVC
- 角度控制器结构
- 如何在Jquery中发布后将值从视图返回到控制器
- 将值从html传递到AngularJS控制器
- 从我的控制器返回一个不同于200的代码以触发ajax错误,这被认为是一种好的做法吗
- 从控制器继承了隔离的作用域以生成可重用的指令
- AngularJS$scope在指令中编译控制器时未定义
- Angular - 编译指令后无法访问控制器方法
- 使用来自我的控制器的数据编译 html 模板
- 在单元测试中获取控制器的编译模板
- 从控制器访问尚未编译的指令DOM元素
- 为什么typescript要用angular编译掉基控制器的局部变量?
- 链接、控制器和编译函数中的各种注入物是什么
- 动态编译由javascript插入的angular控制器