Reputation: 797
I have a angular directive with the following snippet of code, how would I unit test this?
link: function($scope, iElm) {
$(iElm).on('paste', function(){
$timeout(function(){
$scope.lastScan = Date.now();
});
});
}
Upvotes: 0
Views: 570
Reputation: 4862
You need to use $timeout.flush()
which will instantly call any $timeout
callbacks you have defined, so it essentially makes it into synchronous code for testing purposes.
Try this:
app.js
app.directive('myDirective', function($timeout){
return function($scope, iElm) {
// no need to use jQuery
iElm.bind('paste', function(){
console.log('**paste**')
$timeout(function(){
console.log('timeout')
$scope.lastScan = Date.now();
});
});
// $(iElm).on('paste', function(){
// $timeout(function(){
// $scope.lastScan = Date.now();
// });
// });
}
});
appSpec.js
describe("My directive", function() {
var element,
$timeout, $compile, $scope;
// load the module that has your directive
beforeEach(module('plunker'));
beforeEach(inject(function(_$timeout_, _$compile_, _$rootScope_) {
$timeout = _$timeout_;
$compile = _$compile_;
$scope = _$rootScope_.$new();
}));
function compileElement(){
// use $compile service to create an instance of the directive
// that we can test against
element = $compile('<my-directive></my-directive>')($scope);
// manually update scope
$scope.$digest();
}
it("defines a 'lastScan' property", function() {
compileElement();
// trigger paste event
element.triggerHandler('paste');
// angular doesn't know about paste event so need
// to manually update scope
$scope.$digest();
// immediately call $timeout callback
// thus removing any asynchronous awkwardness
$timeout.flush();
// assert that directive has added property to the scope
expect($scope.lastScan).toBeDefined();
});
});
Upvotes: 1