2016-01-21 75 views
1

我正在测试AngularJS指令的控制器。Jasmine:控制器已定义,但其方法未定义

describe('The directive', function() { 
    var element, 
     scope; 

    beforeEach(module('app')); 
    beforeEach(module('path/to/theDirective')); 

    beforeEach(inject(function($compile, $rootScope) { 
     element = angular.element('<div args="args" the-directive ></div>'); 
     scope = $rootScope; 
     $compile(element)(scope); 
     scope.args = { 
      availableValues : [1, 2, 3], 
      key : 'id', 
      selectedValues : [], 
      searchText : '', 
      flag: false 
     }; 
     scope.$digest();   
    })); 

    it('should compile', function() { 
     expect(element.html()).not.toBeNull(); 
    }); 

    describe('directive controller', function() { 
     var controller; 

     beforeEach(inject(function($controller) { 
      controller = element.controller('theDirective', { 
       $scope: scope 
      }); 
     })); 

     it('should exist', function() { 
      expect(controller).not.toBeNull(); 
      expect(controller).toBeDefined(); 
      expect(scope.disableAddButton()).toBeDefined(); 
     }); 
    }); 
}); 

第一个it块通过,所以指令编译成功。第二个describe块未通过。前两个断言在第二个describeit通过,但第三个不通过。它返回TypeError: 'undefined' is not a function (evaluating 'scope.disableAddButton()')。是否有可能控制器没有正确注入,或者是否有更多设置需要完成?

回答

1

事实证明,范围需要被隔离,因为指令的控制器是一个私有函数。

scope.$digest();之后加scope = element.isolateScope() || element.scope();就行了。另外,将控制器声明移至第一个beforeEach块也不是一个坏主意。

固定的测试应该是这样的:

describe('The directive', function() { 
    var element, 
     scope, 
     theController; 

    beforeEach(module('app')); 
    beforeEach(module('path/to/theDirective')); 

    beforeEach(inject(function($compile, $rootScope) { 
     element = angular.element('<div args="args" the-directive ></div>'); 
     scope = $rootScope; 
     $compile(element)(scope); 
     scope.args = { 
      availableValues : [1, 2, 3], 
      key : 'id', 
      selectedValues : [], 
      searchText : '', 
      flag: false 
     }; 
     scope.$digest();  
     theController = element.controller('theDirective');  
     scope = element.isolateScope() || element.scope(); 
    })); 

    it('should compile', function() { 
     expect(element.html()).not.toBeNull(); 
    }); 

    describe('directive controller', function() { 
     it('should exist', function() { 
      expect(theController).not.toBeNull(); 
      expect(theController).toBeDefined(); 
      expect(scope.disableAddButton()).toBeDefined(); 
     }); 
    }); 
});