Unit Test Angularjs directive, which contains private timeout, with Jasmine

后端 未结 1 1423
闹比i
闹比i 2020-12-04 03:56

I have a directive, which should behave differently, depending on how much time passed since it\'s initialization:

am.directive(\'showText\', () => ({
  r         


        
相关标签:
1条回答
  • 2020-12-04 04:32

    The reason why this happens is that $timeout.cancel(visibilityCheckTimeout) launches unconditionally and immediately. Instead, it should be

    $scope.$on('$destroy', () => $timeout.cancel(visibilityCheckTimeout));
    

    There are things that can be done to improve testability (besides the fact that $timeout works here as one-time scope watcher and asks to be replaced with the one).

    $timeout can be successfully spied:

    beforeEach(module('app', ($provide) => {
      $provide.decorator('$timeout', ($delegate) => {
        var timeoutSpy = jasmine.createSpy().and.returnValue($delegate);
        angular.extend(timeoutSpy, $delegate);
        spyOn(timeoutSpy, 'cancel').and.callThrough();
        return timeoutSpy;
      });
    }));
    

    Private $timeout callback can be exposed to scope.

    $scope._visibilityCheckHandler = () => {
      if (parseInt($scope.value, 10) < 100) {
        $scope.textVisible = true;
      }
    };
    $timeout($scope._visibilityCheckHandler, 330);
    

    This way all of the calls can be spied and get full coverage:

    let directiveScope;
    ...
    
    const element = $compile(`...`)($scope);
    
    directiveScope = element.isolateScope();
    spyOn(directiveScope, '_visibilityCheckHandler').and.callThrough();
    
    $scope.$digest();
    ...
    
    expect($timeout).toHaveBeenCalledWith(directiveScope._visibilityCheckHandler, 330);
    expect($timeout.cancel).not.toHaveBeenCalled();
    

    In this case here's no need to have separate specs for '>= 0.33s' and '< 0.33s' with flush delay argument, $timeout's inner work was already tested in Angular specs. Also, callback logic can be tested separately from $timeout spec.

    0 讨论(0)
提交回复
热议问题