Reputation: 10964
I have the following angular directive, which adds a tooltip when I hover over a span.
angular.module('mainMod')
.directive('toolTip', [function() {
return {
restrict: 'A',
scope: {
theTooltip: '@toolTip'
},
link: function(scope, element, attrs){
element.tooltip({
delay: 0,
showURL: false,
bodyHandler: function() {
return jQuery('<div class="hover">').text(scope.theTooltip);
}
});
}
}
}])
;
<span ng-show="data.tooltip" class="icon" tool-tip="{{data.tooltip}}"></span>
I'm looking to write a unit test for this directive, atm I can't use jasmine-jquery.
I'm fairly new to writing unit tests, could anyone possibly help me out?
Give me some pointers or point me towards some helpful resources?
Any advice or suggestions would be greatly appreciated.
What I have atm isn't much...
describe('Unit testing tooltip', function() {
var $compile;
var $rootScope;
// Load the myApp module, which contains the directive
beforeEach(module('mainMod'));
// Store references to $rootScope and $compile
// so they are available to all tests in this describe block
beforeEach(inject(function(_$compile_, _$rootScope_){
// The injector unwraps the underscores (_) from around the parameter names when matching
$compile = _$compile_;
$rootScope = _$rootScope_;
}));
it(' ', function() {
// Compile a piece of HTML containing the directive
FAILS HERE --> var element = $compile("<span class='icon' tool-tip='{{data.tooltip}}'></span>")($rootScope);
$rootScope.$digest();
});
});
It's failing with a message of
TypeError: undefined is not a function
I think it's being caused by the ($rootScope) at the end of the line I've specified above.
Upvotes: 1
Views: 2628
Reputation: 1738
You have to wrap your DOM content with angular.element first before compiling it. I am not sure what the tooltip module you are using but I used the jQuery UI tooltip instead.
//create a new scope with $rootScope if you want
$scope = $rootScope.$new();
var element = angular.element("<span class='icon' tool-tip='This is the tooltip data'></span>");
//use the current scope has just been created above for the directive
$compile(element)($scope);
One more thing, because you are using isolate scope in your directive, to get the current scope from your directive, you need to call
element.isolateScope()
based on this reference : How to Unit Test Isolated Scope Directive in AngularJS
For a working fiddle, you can found it here : http://jsfiddle.net/themyth92/4w52wsms/1/
Upvotes: 2
Reputation: 7214
Any unit test is basically the same - mock the environment, construct the unit, check that the unit interacts with the environment in the expected manner. In this instance, you'd probably want to mock the tooltip creator
spyOn(jQuery.fn, 'tooltip');
then compile some template using the directive (which you're already doing), then simulate the hover event on the compiled element and then check that the tooltip creator was called in the expected manner
expect(jQuery.fn.tooltip).toHaveBeenCalledWith(jasmine.objectContaining({
// ... (expected properties)
}));
How you simulate the event depends on how the element.tooltip
is supposed to work. If it really works the way you're using it in the question code, you don't need to simulate anything at all and just check the expected interaction right after template compilation.
Upvotes: -1