我们说我已经建立了非常简单的指令:
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 ''
现在,我可以使用这样的测试轻松测试指令是否正确编译:
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'")
现在,我该如何测试mouseenter
的行为?我的意思是首先我不知道如何达到控制器的胆量。而且我也不知道如何从测试中访问moment.js
(我使用kocha与mocha)。
我应该将moment.js
内容转换为ng-service依赖吗?然后它意味着使用的每一件事我都必须作为角度服务导入?或者我可能只是在测试中使用browserify?然后每个spec文件都必须独立浏览,因为测试没有单一的入口点。
答案 0 :(得分:2)
首先,您必须在配置文件中添加moment.js
作为业力依赖(通常命名为karma.conf.js ...至少对于Node项目而言)。这样您就可以从测试中访问它。其次,这就是我写测试的方式:
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);
});
});
希望这会有所帮助。 注意此代码尚未经过测试,因此可能需要进行一些调整以满足您的需求。
注意2 我刚刚注意到我也在Jasmine中编写了这个测试。如果它不容易理解,请告诉我。