0

I have a function in angular directive that gets triggered on watch. How do i test the timeout based scrolling activity of the function scroll since its not in scope?

scope.$watch('elementId', function(value) {
    //How do i test scroll function contents?
    scroll(element, value);
});

function scroll (pE, element) {
   console.log('Here');
   $timeout(function afterTimeout () {
     var scrollTo = $('#' + element);
     var container = $(pE);
     container.animate({scrollTop : scrollTo[0].offsetTop - container[0].offsetTop - 10}, 'slow');
   }, 250);
}

The detailed code is here http://jsfiddle.net/QGmCF/68/

Andrew Eisenberg
  • 28,387
  • 9
  • 92
  • 148
meteor
  • 2,518
  • 4
  • 38
  • 52
  • 1
    Unit-testing a real DOM isn't very pleasing task. See this http://stackoverflow.com/a/37527210/3731501 on how to test $timeout calls. Since it is not in scope, you already know that it would be easier to test if it were on scope. Expose `scroll` function as scope/controller method, this will benefit testability. – Estus Flask Oct 01 '16 at 02:16
  • Ah okay..will take a look at that.thanks! – meteor Oct 04 '16 at 23:51

1 Answers1

1

I have a few suggestions to clean up your code. The first thing to realize is that you should be injecting the mock $timeout object into your test and calling $timeout.flush(251) to make sure your code runs.

Like this:

it('test watch', inject(function($compile, $rootScope, $timeout) {
    // as before
    $timeout.flush(251);
    // test that your code has run
}));

Another suggestion: instead of using jQuery's $ object, use $window.document or $document[0] to access the browser's native components. With this, you can write this:

var scrollTo = $document[0].getElementById(element);

and then you no longer have to access your scrollTo element with [0].

Andrew Eisenberg
  • 28,387
  • 9
  • 92
  • 148