使用模板URL测试指令

时间:2013-06-18 16:39:30

标签: testing angularjs jasmine directive

我正在尝试测试使用templateURL的angularJS指令。对于我的生活,我无法让编译器实际加载templateURL,即使它已被放入templateCache。我意识到业力预处理所有模板内容并为每个预加载templateCache的模块创建模块,但我预计这将是等效的。

这是一个http://jsfiddle.net/devshorts/cxN22/2/,展示了最新进展。

angular.module("app", [])
.directive("test", function(){
    return {
        templateUrl:"some.html",
        replace:true
    }
});

//--- SPECS -------------------------

describe("template url test", function() {
    var element,  scope, manualCompiledElement;

    beforeEach(module('app'));

    beforeEach(inject(function($rootScope, $controller, $compile, $templateCache){
        $templateCache.put("some.html", "<div>hello</div>");

        scope = $rootScope.$new();

        element = $compile(angular.element('<test></test>'))(scope);

        manualCompiledElement = $compile(angular.element($templateCache.get('some.html')))(scope);

        scope.$digest();        
    }));

    it("has hello", function() {
        expect(element.text()).toContain('hello');
    });

    it("template cache has contents", function(){
        expect(manualCompiledElement.text()).toContain('hello');
    });       
});

我错过了什么?

2 个答案:

答案 0 :(得分:2)

我意识到你不再需要知道,但在我看来,有两个问题对此有所贡献。

第一个被@ Words-Like-Jared指出。您将指令定义为限制为属性(默认),但将其用作元素。所以你需要restrict: 'E'

第二个问题是您的模板永远不会被实际检索,并且您的编译/链接永远不会完成。指令中模板内容的请求是异步的,因此需要根据作用域的摘要来解析承诺并返回它们,类似于另一个问题的this answer

执行手动编译时,结果不是异步的,会立即检索模板。实际上,手动编译中的编译并没有做很多工作,因为您正在编译模板的内容,而模板中没有任何指令。

现在在beforeEach使用

的末尾
$scope.$digest()

你正在消化目前的范围及其子女。当您使用$rootScope.$digest()$scope.$apply()时,您将在所有范围内执行摘要。所以改成这个

$rootScope.$digest()
// or
$scope.$root.$digest()
编译后的行中的

表示您的两个测试现在都将通过。我更新了小提琴here

答案 1 :(得分:1)

Here is a variation of the solution in coffeescript

expect = chai.expect;
app = angular.module('TM_App')

app.directive "test", ()->
  templateUrl:"some.html",
  replace    :true


describe '|  testing | templateUrl',->
  element = null

  beforeEach ->
    module('TM_App')

  beforeEach ->
    inject ($compile,$rootScope, $templateCache)->
      $templateCache.put "some.html", "<div>hello {{name}}</div>"
      scope       = $rootScope.$new();
      element     = $compile('<test/>')(scope);
      scope.name = 'John'
      scope.$digest()

  it "has hello", ()->
    expect(element.text()      ).to.equal 'hello John'
    expect(element[0].outerHTML).to.equal '<div class="ng-binding">hello John</div>'