Angularjs 测试指令的正确方法
假设我构建了非常简单的指令:Angularjs 测试指令的正确方法,angularjs,unit-testing,mocha.js,karma-runner,browserify,Angularjs,Unit Testing,Mocha.js,Karma Runner,Browserify,假设我构建了非常简单的指令: moment = require 'moment' # as you can see I'm using browserify ### whenever mouse hovered, it shows relative time ### app.directive 'simpleDirective',-> restrict: 'E' scope: date:'=' template: "<div class='nice-date
moment = require 'moment' # as you can see I'm using browserify
### whenever mouse hovered, it shows relative time ###
app.directive 'simpleDirective',->
restrict: 'E'
scope: date:'='
template: "<div class='nice-date' date='date' ng-mouseenter='hover = true'
ng-mouseleave='hover = false'>{{niceDate}}</div>"
controller: ($scope)->
$scope.$watch 'hover',->
$scope.niceDate = if $scope.hover
moment($scope.date).fromNow()
else ''
moment=require'moment'#如您所见,我正在使用browserify
###每当鼠标悬停时,它都会显示相对时间###
app.directive'simpleDirective',->
限制:“E”
范围:日期:'='
模板:“{niceDate}}”
控制器:($scope)->
$scope.$watch'hover',->
$scope.niceDate=如果$scope.hover
时刻($scope.date).fromNow()
否则“
现在,我可以使用如下测试轻松测试指令是否正确编译:
describe 'simpleDirective test', ->
$compile = $rootScope = undefined
beforeEach module('myApp')
beforeEach inject (_$compile_, _$rootScope_) ->
$compile = _$compile_
$rootScope = _$rootScope_
it 'Replaces the element with the appropriate content', ->
var element = $compile("<simple-directive date='mydate' />")($rootScope)
$rootScope.$digest()
expect(element.html()).toContain("class='nice-date'")
描述“简单直接测试”,->
$compile=$rootScope=未定义
在每个模块之前('myApp')
每次注入之前($compile,$rootScope)->
$compile=\$compile_
$rootScope=\$rootScope_
它“用适当的内容替换元素”,->
var元素=$compile(“”)($rootScope)
$rootScope.$digest()
expect(element.html()).toContain(“class='nice-date'))
现在,如何测试mouseenter
的行为?我的意思是,首先,我不知道如何进入控制器的内部。而且,我也不知道如何从测试中访问moment.js
(我正在用卡玛和摩卡)
我应该把
moment.js
东西变成ng服务依赖吗?那就意味着每一件我用过的东西都要作为角度服务导入?或者我只是在测试中使用browserify?然后,每个spec文件都必须单独浏览,因为测试没有单一的入口点 首先,您必须在配置文件中添加moment.js
作为karma依赖项(通常命名为karma.conf.js…至少对于节点项目是如此)。这样,您就可以从测试中访问它。其次,这是我编写测试的方式:
describe('simlpleDirective', function() {
var $scope, $compile;
beforeEach(module('myApp'));
beforeEach(inject($rootScope, _$compile_) {
// Always create a new scope to prevent permanently dirtying the root scope for other tests
$scope = $rootScope.$new();
$compile = _$compile_
});
it('Replaces element with content or something like that', function() {
// Abstract the date so that you can test it later
var date = new Date(),
element;
$scope.mydate = date;
$scope.$apply(function() {
element = $compile("<simple-directive date='mydate'></simple-directive>")($scope);
});
// You have full access to the compiled element here
expect(element.find('.nice-date').text()).toBe('');
// You also have access to $scope variables here
expect($scope.niceDate).toBe('');
// You should probably wrap the hover stuff in another test, but I'm being lazy here
formattedDate = moment(date).fromNow();
// Manually trigger the hover event
element.find('.nice-date').triggerHandler('mouseenter');
// Now check one or both again
// $scope.$apply or $scope.$digest might be necessary here
expect(element.find('.nice-date').text()).toBe(formattedDate);
expect($scope.niceDate).toBe(formattedDate);
});
});
description('simlpleDirective',function(){
var$scope$compile;
在每个模块之前(模块(‘myApp’);
beforeach(注入($rootScope,$compile){
//始终创建一个新的作用域,以防止将根作用域永久性地弄脏用于其他测试
$scope=$rootScope.$new();
$compile=\$compile_
});
它('将元素替换为内容或类似内容',函数(){
//提取日期,以便稍后进行测试
变量日期=新日期(),
元素;
$scope.mydate=日期;
$scope.$apply(函数(){
元素=$compile(“”)($scope);
});
//您可以在此完全访问已编译的元素
expect(element.find('.nice date').text()).toBe('');
//您还可以在此处访问$scope变量
预期($scope.niceDate.)为(“”);
//你可能应该在另一个测试中包装悬停的东西,但我在这里很懒
formattedDate=时刻(日期).fromNow();
//手动触发悬停事件
元素.find('.nice date').triggerHandler('mouseenter');
//现在再次检查其中一个或两个
//此处可能需要$scope.$apply或$scope.$digest
expect(element.find('.nice date').text()).toBe(formattedDate);
expect($scope.niceDate).toBe(formattedDate);
});
});
希望这能有所帮助注意此代码尚未测试,因此可能需要一些调整以满足您的需要
注2我刚刚注意到我也用Jasmine编写了这个测试。如果不容易理解,请告诉我。太棒了,迈克!谢谢。我试试看。茉莉花不是问题。我只是需要从一个大的角度来看待它。