将Jasmine angular指令编译为对象

时间:2016-02-12 14:54:17

标签: javascript angularjs jasmine directive angular-mock

我正在测试一个Angular指令,这个测试过去曾用过Angular 1.4.9。我最近升级到1.5.0,所以我认为这个问题/(意外结果)可能是由于angular-mocks

describe('The buttonToggle directive', function() {
  var $compile,
    btElement = '<button-toggle></button-toggle>',
    compiledElement,
    btElementPath = 'button-toggle.html',
    $scope;

  beforeEach(inject(function(_$compile_, $templateCache, $rootScope) {
    $compile = _$compile_;
    $scope = $rootScope.$new();
    var template = $templateCache.get(btElementPath);
    $templateCache.put(btElementPath, template);
    var element = angular.element(btElement);
    compiledElement = $compile(element)($scope);
    console.log(compiledElement);
    $scope.$digest();
    console.log(compiledElement);
  }));

  it('should compile', function() {
    expect(compiledElement.html()).toContain('btn');
  });
});

compiledElement正被放入一个对象中。以下是console.log的返回值:

{0: <button-toggle class="ng-scope"></button-toggle>, length: 1}

我不明白为什么会这样。它应该编译成button-toggle.html内容。

编辑:忘记在beforeEach中注入buttonToggle模块。我是否还需要注入主应用模块?如果我插入它,那么我会得到一个undefined is not an object (evaluation compiledElement.html)

模块注射:

beforeEach(module('ocapp.buttonToggle'));
beforeEach(module('ocapp'));

编辑2:我不再认为这是angular-mocks版本问题。我的指令取决于在单独文件中定义的控制器,并且它没有被解析。

按钮-toggle.directive.js

(function() {
  'use strict';

  angular
    .module('ocapp.buttonToggle')
    .directive('buttonToggle', buttonToggle);

  function buttonToggle(ButtonToggleController) {
    return {
      restrict: 'E',
      templateUrl: 'app/button-toggle/button-toggle.html',
      replace: true,
      scope: {
        on: '='
      },
      controller: ButtonToggleController
    };
  }
})();

button-toggle.html与此处使用的所有其他文件位于同一目录中,也许我不需要templateUrl属性中的扩展路径?

编辑3:我已经解决了所有其他问题,并回到原点。

按钮-toggle.directive.spec.js

describe('The buttonToggle directive', function() {
  var $compile,
    btElement = '<button-toggle></button-toggle>',
    compiledElement,
    btElementPath = 'app/button-toggle/button-toggle.html',
    $scope,
    $httpBackend;

  beforeEach(module('ocapp.buttonToggle'));
  //beforeEach(module('ocapp'));

  beforeEach(inject(function(_$compile_, $templateCache, $rootScope, $injector) {
    $compile = _$compile_;
    $scope = $rootScope.$new();
    $httpBackend = $injector.get('$httpBackend');
    $httpBackend.whenGET(btElementPath).respond(200, '');
    var template = $templateCache.get(btElementPath);
    $templateCache.put(btElementPath, template);
    var element = angular.element(btElement);
    compiledElement = $compile(element)($scope);
    console.log(compiledElement);
    $scope.$digest();
  }));

  it('should compile', function() {
    expect(compiledElement.html()).toContain('btn');
  });
});

有关如何从指令中的同一模块定义外部控制器,请参阅this question and accepted answer

按钮-toggle.directive.js

(function() {
  'use strict';

  angular
    .module('ocapp.buttonToggle')
    .directive('buttonToggle', buttonToggle);

  function buttonToggle() {
    return {
      restrict: 'E',
      templateUrl: 'app/button-toggle/button-toggle.html',
      replace: true,
      scope: {
        on: '='
      },
      controller: 'ButtonToggleController'
    };
  }
})();

1 个答案:

答案 0 :(得分:1)

结果证明它不是Angular版本问题,而是缺少依赖项。

  1. 使用npm安装karma-ng-html2js-preprocessor
  2. 修改karma.conf.js
  3. 将指令&{39}更改为templateUrl
  4. 测试应如下所示。
  5. karma.conf.js 补充

    'button-toggle.html'

    按钮-toggle.directive.spec.js

    preprocessors: {
       '**/*.html': ['ng-html2js']
    },
    
    ngHtml2JsPreprocessor: {
       stripPrefix: 'app/button-toggle/'
       moduleName: 'templates'
    },