Karma单元使用externalUrl测试Angular JS指令

时间:2014-11-24 18:49:02

标签: javascript angularjs unit-testing karma-runner

我正在尝试测试具有外部模板的Angular指令,但无法使其工作。这是我第一次尝试使用Karma。我已经搜索了一个解决方案,并尝试对karma.conf.js文件进行各种更改,但仍然继续这样做:

Error: [$injector:modulerr] Failed to instantiate module app/inventory/itemDetails.html due to:
Error: [$injector:nomod] Module 'app/inventory/itemDetails.html' is not available! You     either misspelled the module name or forgot to load it. 

文件夹结构:

app
  inventory
    itemDetails.html
    itemDetailsDirective.js  (templateUrl: "app/inventory/itemDetails.html")


UnitTest
  karma.conf.js
    specs
      inventorySpec.js

karma.conf.js

  // list of files / patterns to load in the browser
files: [
  '../scripts/jquery.min.js',
  'scripts/angular.js',
  'scripts/angular-mocks.js',
  '../app/*.js',
  '../app/**/*.js',
  '../app/inventory/itemDetails.html',
  'specs/*.js'
  ],


preprocessors: {
    '../app/inventory/itemDetails.html':['ng-html2js'] // Is this supposed to be the path relative to the karma.conf.js file?
  },

ngHtml2JsPreprocessor: {
    stripPrefix: '../',
  },

itemDetailsDirective.js

templateUrl: "app/inventory/itemDetails.html",

inventorySpec.js(大部分内容已被注释用于调试目的)

describe("itemDetailsDirective", function () {
    var element, $scope;

    beforeEach(module("app/inventory/itemDetails.html"));

    beforeEach(inject(function ($compile, $rootScope) {
        console.log("itemDetailsDirective");
        //element = angular.element('<item-details></item-details>');
        //$scope = $rootScope.$new();
        //$compile(element)($scope);
        //$scope.$digest();
    }));

    it('should display', function () {
    //    var isolatedScope = element.isolateScope();
    //    //expect(isolatedScope.condition).toEqual("Fair");
    });

});

所以我有一个与app文件夹并行的UnitTest文件夹(VS 2013项目)。 &#34;文件&#34;下的路径在karma.conf.js是正确的 - 所有&#34;非模板Url&#34;测试工作正常。

帮助会很棒,而我还有一些头发!

2 个答案:

答案 0 :(得分:2)

我得到了这个工作,感谢我刚刚遇到的这篇文章:http://willemmulder.net/post/63827986070/unit-testing-angular-modules-and-directives-with

关键是路径是相对于DISK根的!

为了说明,我更改了karma.conf.js文件以使用cahceIdFromPath:

ngHtml2JsPreprocessor: {
    cacheIdFromPath : function(filepath) {
        console.log("karma, cacheIdFromPath " + filepath);
        var templateFile = filepath.substr(filepath.indexOf("/app/") + 1 );
        console.log("karma, templateFile: " + templateFile);
    return templateFile;
  },
},

输出:

karma, cacheIdFromPath C:/Dev/BcCom/app/inventory/itemDetails.html
karma, templateFile: app/inventory/itemDetails.html

有了上述内容,它现在可以正常工作了!

答案 1 :(得分:0)

我不确定你想要测试什么,但是你试图使用html作为我认为不正确的模块,可能你必须使用$httpbackend来模拟GET请求。我做了一个虚拟的例子:

'use strict';
describe('TestMyDirective', function() {
  var $compile, $http, $httpBackend, $rootScope, $scope, template;

  beforeEach(module('myApp'));

  beforeEach(inject(function($injector) {
    $rootScope = $injector.get('$rootScope');
    $compile = $injector.get('$compile');
    // Inject $httpBackend service
    $httpBackend = $injector.get('$httpBackend');
    // Mock request to your html
    $httpBackend.whenGET('my.html').respond("GotIT");
    $scope = $rootScope.$new();
    template = $compile("<my-directive> </my-directive>")($scope);
    $scope.$digest();
  }));

  /*
   *
   * Tests
   *
   */
  describe('Test something', function() {
    it('should test something', function() {
       // You can test that your directive add something on the $scope
    });
  });
});