在单元测试中访问已编译的模板

时间:2014-11-19 20:43:30

标签: angularjs unit-testing jasmine

大多数Angular教程都讨论了使用Protractor进行端到端测试来测试编译模板是否按预期出现。我想知道是否可以通过单元测试来完成这项工作。

大多数关于在单元测试中引用HTML代码的教程都描述了在测试中编译自己编写的代码,例如,以确保正确访问指令:

describe('some function', function () {
  it('should do something', inject(function ($compile, $rootScope) {
    var element = $compile('<div id = "foo" ng-hide = "somecondition">Bar</div>')($Scope);
    $rootScope.digest();
    //Search for a given DOM element and perform some test here
  }));
});

但是,我想说我想测试实际模板文件中的代码。就像我想测试ng-hide是否成功设置一样。我希望能够做到这样的事情:

describe('some function', function () {
  it('should do something', function () {
    //Get the div with ID 'foo' in the compiled template
    var elm = $('#foo');
    expect(elm.css('display')).toEqual('none');
  });
});

当我这样做时,这不起作用。 elm设置为某些HTML / Javascript代码,但不是模板的代码,elm.css('display')以未定义的形式返回。

有没有办法用Jasmine / Angular设置单元测试?

2 个答案:

答案 0 :(得分:7)

使用ng-html2js将HTML模板加载到Angular的$templateCache中,以便在测试中使用它们。

在测试中检索您的特定模板:

var template = $templateCache.get('my/template.html');

将模板包装在更易于使用的jqLit​​e / jQuery对象中:

var element = angular.element(template);

然后您可以选择模板中的元素:

var fooEl = element.find('#foo');

对于断言,您不想测试在元素上设置display: none,该元素正在测试ng-hide的内部实现。您可以相信Angular团队有自己的测试,涵盖设置CSS属性。相反,您要测试您是否正确编写了模板,因此它更适合测试元素上ng-hide属性的存在,并且它提供了正确的范围要绑定的属性:

expect(fooEl.attr('ng-hide')).toBe('isFooElHidden');

答案 1 :(得分:3)

除了 @ user2943490 的正确答案:

  • 最好定义专用范围,而不是使用 $ rootScope var scope = $rootScope.$new(); var element = $compile(template)(scope);

  • 在大多数情况下,您希望从内部指令的范围测试属性。你可以在你的beforeEach方法中定义它,并在所有测试中访问它: var isolatedScope = element.isolateScope(); expect(isolatedScope.property).toEqual(value);