Ken*_*nne 66 unit-testing jasmine angularjs angularjs-directive karma-runner
在Vojta Jina的优秀存储库中,他演示了指令的测试,他在模块包装器之外定义了指令控制器.请参见:https: //github.com/vojtajina/ng-directive-testing/blob/master/js/tabs.js
这不是不好的做法并污染全局命名空间吗?
如果一个人有另一个地方可以合理地调用TabsController,那会不会打破这些东西?
所提到的指令的测试可以在这里找到:https://github.com/vojtajina/ng-directive-testing/commit/test-controller
是否可以将指令控制器与指令的其余部分分开测试,而无需将控制器放在全局命名空间中?
将整个指令封装在app.directive(...)定义中会很好.
Jam*_*yke 75
我有时更喜欢将控制器和指令一起包含在内,所以我需要一种方法来测试它.
首先是指令
angular.module('myApp', [])
.directive('myDirective', function() {
return {
restrict: 'EA',
scope: {},
controller: function ($scope) {
$scope.isInitialized = true
},
template: '<div>{{isInitialized}}</div>'
}
})
Run Code Online (Sandbox Code Playgroud)
然后测试:
describe("myDirective", function() {
var el, scope, controller;
beforeEach inject(function($compile, $rootScope) {
# Instantiate directive.
# gotacha: Controller and link functions will execute.
el = angular.element("<my-directive></my-directive>")
$compile(el)($rootScope.$new())
$rootScope.$digest()
# Grab controller instance
controller = el.controller("myDirective")
# Grab scope. Depends on type of scope.
# See angular.element documentation.
scope = el.isolateScope() || el.scope()
})
it("should do something to the scope", function() {
expect(scope.isInitialized).toBeDefined()
})
})
Run Code Online (Sandbox Code Playgroud)
有关从实例化指令获取数据的更多方法,请参阅angular.element文档.
请注意,实例化该指令意味着控制器和所有链接函数已经运行,因此可能会影响您的测试.
pko*_*rce 58
好问题!
因此,这是一个常见的问题,不仅与控制器有关,而且可能与指令可能需要执行其工作的服务有关,但不一定要将此控制器/服务暴露给"外部世界".
我坚信全球数据是邪恶的,应该避免,这也适用于指令控制器.如果我们采用这种假设,我们可以采用几种不同的方法来"本地"定义这些控制器.在这样做时我们需要记住,控制器应该仍然可以"轻松"访问单元测试,因此我们不能简单地将其隐藏到指令的闭包中.IMO的可能性是:
1)首先,我们可以简单地在模块级别定义指令的控制器,ex ::
angular.module('ui.bootstrap.tabs', [])
.controller('TabsController', ['$scope', '$element', function($scope, $element) {
...
}])
.directive('tabs', function() {
return {
restrict: 'EA',
transclude: true,
scope: {},
controller: 'TabsController',
templateUrl: 'template/tabs/tabs.html',
replace: true
};
})
Run Code Online (Sandbox Code Playgroud)
这是我们在https://github.com/angular-ui/bootstrap/blob/master/src/tabs/tabs.js中使用的一种简单技术,它基于Vojta的工作.
虽然这是一种非常简单的技术,但应该注意控制器仍然暴露给整个应用程序,这意味着其他模块可能会覆盖它.从这个意义上说,它使一个控制器成为AngularJS应用程序的本地控制器(因此不会污染全局窗口范围),但它也是所有AngularJS模块的全局控制器.
2)使用闭包范围和特殊文件设置进行测试.
如果我们想完全隐藏控制器函数,我们可以将代码包装在一个闭包中.这是AngularJS正在使用的一种技术.例如,查看NgModelController,我们可以看到它在自己的文件中定义为"全局"函数(因此可以方便地进行测试),但整个文件在构建期间被包装在闭包中:
总结一下:选项(2)"更安全",但需要对构建进行一些预先设置.
小智 9
詹姆斯的方法适合我.但是,当你有一个外部模板时,你必须在$ rootScope.$ digest()之前调用$ httpBackend.flush()才能让angular执行你的控制器.
我想这应该不是问题,如果你使用https://github.com/karma-runner/karma-ng-html2js-preprocessor
归档时间: |
|
查看次数: |
31592 次 |
最近记录: |