I never had to test my angularjs directives before, also the directives I wrote for my current company is uses events to communicated directives to directives and services.
And so I wrote a directive, e.g. a search directive.
<m-search />
This directive broadcasts "searchbox-valuechanged"
event and the key, now I have to write tests for it.
'use strict';
describe('<m-search>', function() {
beforeEach(module('hey.ui'));
var rootScope;
beforeEach(inject(function($injector) {
rootScope = $injector.get('$rootScope');
spyOn(rootScope, '$broadcast');
}));
it("should broadcast something", function() {
expect(rootScope.$broadcast).toHaveBeenCalledWith('searchbox-valuechanged');
});
});
Update On change on the input,
<input class="m-input m-input--no-border" type="search" placeholder="Search"
ng-model="ctrl.searchValue"
ng-model-options="{debounce: 100}"
ng-change="ctrl.onChange({search: ctrl.searchValue})">
It calls a method in the directive's controller
vm.onChange = function (searchValue) {
$rootScope.$broadcast('searchbox-valuechanged', {data: searchValue});
};
How do I test broadcasting?
Here's how I'd do it...
describe('m-search directive', function() {
var ctrl, // your directive's controller
$rootScope; // a reference to $rootScope
beforeEach(function() {
// bootstrap your module
module('hey.ui');
inject(function($compile, _$rootScope_) {
$rootScope = _$rootScope_;
// see https://docs.angularjs.org/api/ngMock/function/angular.mock.inject#resolving-references-underscore-wrapping-
// create an instance of your directive
var element = $compile('<m-search></m-search')($rootScope.$new());
$rootScope.$digest();
// get your directive's controller
ctrl = element.controller('mSearch');
// see https://docs.angularjs.org/api/ng/function/angular.element#methods
// spy on $broadcast
spyOn($rootScope, '$broadcast').and.callThrough();
});
});
it('broadcasts searchbox-valuechanged on change', function() {
var searchValue = {search: 'search string'};
ctrl.onChange(searchValue);
expect($rootScope.$broadcast).toHaveBeenCalledWith(
'searchbox-valuechanged', {data: searchValue});
});
});
You'll note this doesn't rely on your directive's template at all. I don't believe template functionality is in the realm of unit testing; that's something best left to e2e testing with protractor. Unit testing is about testing the API of your components to ensure they do what they're meant to do.