angularjs - Proper way of testing directives -
let's i've built simple directive:
moment = require 'moment' # can see i'm using browserify ### whenever mouse hovered, 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 ''
now, can test if directive compiles, using test this:
describe 'simpledirective test', -> $compile = $rootscope = undefined beforeeach module('myapp') beforeeach inject (_$compile_, _$rootscope_) -> $compile = _$compile_ $rootscope = _$rootscope_ 'replaces element appropriate content', -> var element = $compile("<simple-directive date='mydate' />")($rootscope) $rootscope.$digest() expect(element.html()).tocontain("class='nice-date'")
now, how can test behavior of mouseenter
? mean first of have no idea how guts of controller. , have no idea how access moment.js
tests (i'm using karma mocha).
should turn moment.js
thing ng-service dependency? means every single thing used i'm gonna have import angular service? or maybe use browserify on tests? every single spec file has browserified independently, because there's no single entry point tests.
first, have add moment.js
karma dependency in configuration file (usually named karma.conf.js... @ least node projects anyway). way you'll have access tests. second, how write tests:
describe('simlpledirective', function() { var $scope, $compile; beforeeach(module('myapp')); beforeeach(inject($rootscope, _$compile_) { // create new scope prevent permanently dirtying root scope other tests $scope = $rootscope.$new(); $compile = _$compile_ }); it('replaces element content or that', function() { // abstract date can test later var date = new date(), element; $scope.mydate = date; $scope.$apply(function() { element = $compile("<simple-directive date='mydate'></simple-directive>")($scope); }); // have full access compiled element here expect(element.find('.nice-date').text()).tobe(''); // have access $scope variables here expect($scope.nicedate).tobe(''); // should wrap hover stuff in test, i'm being lazy here formatteddate = moment(date).fromnow(); // manually trigger hover event element.find('.nice-date').triggerhandler('mouseenter'); // check 1 or both again // $scope.$apply or $scope.$digest might necessary here expect(element.find('.nice-date').text()).tobe(formatteddate); expect($scope.nicedate).tobe(formatteddate); }); });
hopefully helps. note code has not been tested might need tweaks suit needs.
note 2 noticed wrote test in jasmine. let me know if it's not easy enough understand.
Comments
Post a Comment