大多数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设置单元测试?
答案 0 :(得分:7)
使用ng-html2js将HTML模板加载到Angular的$templateCache
中,以便在测试中使用它们。
在测试中检索您的特定模板:
var template = $templateCache.get('my/template.html');
将模板包装在更易于使用的jqLite / 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);