Javascript AngularJS指令单元测试中未定义的函数

Javascript AngularJS指令单元测试中未定义的函数,javascript,angularjs,unit-testing,Javascript,Angularjs,Unit Testing,我正在尝试为以下AngularJS指令中定义的toggleDetails函数编写单元测试: angular.module('hadoopApp.cluster.cluster-directive', []) .directive('cluster', [function() { return { templateUrl:'components/cluster/cluster.html', restrict: 'E', replace: true, scope

我正在尝试为以下AngularJS指令中定义的toggleDetails函数编写单元测试:

angular.module('hadoopApp.cluster.cluster-directive', [])

.directive('cluster', [function() {
  return {
    templateUrl:'components/cluster/cluster.html',
    restrict: 'E',
    replace: true,
    scope: {
      clusterData: '=',
      showDetails: '='
    },
    link: function(scope, element, attrs) {
      scope.toggleDetails = function() {
        console.log('Test');
        scope.showDetails = !scope.showDetails;
      };
    },
    // Default options 
    compile: function(tElement, tAttrs){
      if (!tAttrs.showDetails) { tAttrs.showDetails = 'false'; }
    }
  };

}]);
这是单元测试:

'use strict';   
describe('hadoopApp.cluster module', function() {
  // Given
  beforeEach(module('hadoopApp.cluster.cluster-directive'));    

  var compile, mockBackend, rootScope;  
  beforeEach(inject(function($compile, $httpBackend, $rootScope) {
    compile = $compile;
    mockBackend = $httpBackend;
    rootScope = $rootScope;
  }));

  var dummyCluster;
  beforeEach(function() {
    dummyCluster = {
      id:"189",
      name:"hadoop-189",
      exitStatus:0
    };    
    mockBackend.expectGET('components/cluster/cluster.html').respond(
      '<div><div ng-bind="clusterData.name"></div></div>');
  });

  it('should toggle cluster details info', function() {
    var scope = rootScope.$new();
    scope.clusterData = dummyCluster;

    // When
    var element = compile('<cluster' +
      ' cluster-data="clusterData" />')(scope);
    scope.$digest();
    mockBackend.flush();

    // Then
    var compiledElementScope = element.isolateScope();
    expect(compiledElementScope.showDetails).toEqual(false);

    // When
    console.log(compiledElementScope);
    compiledElementScope.toggleDetails();

    // Then
    expect(compiledElementScope.showDetails).toEqual(true);
  });

  afterEach(function() {
    mockBackend.verifyNoOutstandingExpectation();
    mockBackend.verifyNoOutstandingRequest();
  });
});
在compiledElementScope内打印隔离作用域的内容,我可以看到实际上该函数不包含在对象中


因此,看起来toggleDetails函数不包括在隔离范围内,但我不知道为什么。

如果在指令中使用
编译
函数,那么
链接
函数将被忽略。您应该在
compile
方法中返回函数:

        compile: function (tElement, tAttrs) {

            if (!tAttrs.showDetails) {
                tAttrs.showDetails = 'false';
            }
            return {
                post: function (scope, element, attrs) {
                    console.log('Test');
                    scope.toggleDetails = function () {
                        console.log('Test');
                        scope.showDetails = !scope.showDetails;
                    };
                }
            };
        }
此外,为了使测试正常工作,您应该添加:

    scope.showDetails = false;
以及与指令的绑定(因为您需要两个值):

var元素=编译(“”)(范围);

Jsfiddle

谢谢!它工作得很好。我不明白为什么需要
scope.showDetails=false
,因为它的默认选项应该是false。因为您将它绑定为双向绑定变量,如果它是单向变量,它会非常好!我对“=”的实际工作原理知之甚少。
    scope.showDetails = false;
    var element = compile('<cluster' +
        ' cluster-data="clusterData" show-details="showDetails" />')(scope);