我有一个AngularJS指令,有一个templateUrl定义。我试图单元测试它与茉莉花。
我的Jasmine JavaScript看起来像下面,根据this的建议:
describe('module: my.module',function () { beforeEach(module('my.module')); describe('my-directive directive',function () { var scope,$compile; beforeEach(inject(function (_$rootScope_,_$compile_,$injector) { scope = _$rootScope_; $compile = _$compile_; $httpBackend = $injector.get('$httpBackend'); $httpBackend.whenGET('path/to/template.html').passThrough(); })); describe('test',function () { var element; beforeEach(function () { element = $compile( '<my-directive></my-directive>')(scope); angular.element(document.body).append(element); }); afterEach(function () { element.remove(); }); it('test',function () { expect(element.html()).toBe('asdf'); }); }); }); });
TypeError: Object #<Object> has no method 'passThrough'
所有我想要的是templateUrl将被加载,因为 – 我不想使用响应。我相信这可能与它使用ngMock而不是ngMockE2E相关。如果这是罪魁祸首,我如何使用后者而不是前者?
提前致谢!
你是正确的,它与ngMock相关。 ngMock模块会为每个Angular测试自动加载,并初始化模拟$ httpBackend以处理任何使用$ http服务,其中包括模板提取。模板系统尝试通过$ http加载模板,并且它成为模拟的“意外请求”。
你需要一种方法来将模板预装载到$ templateCache中,这样当Angular请求它们时,它们已经可用,而不使用$ http。
首选解决方案:Karma
如果你使用Karma来运行你的测试(你应该是),你可以配置它使用ng-html2js预处理器加载模板。 Ng-html2js读取您指定的HTML文件,并将它们转换为预加载$ templateCache的Angular模块。
步骤1:在karma.conf.js中启用和配置预处理器
// karma.conf.js preprocessors: { "path/to/templates/**/*.html": ["ng-html2js"] },ngHtml2JsPreprocessor: { // If your build process changes the path to your templates,// use stripPrefix and prependPrefix to adjust it. stripPrefix: "source/path/to/templates/.*/",prependPrefix: "web/path/to/templates/",// the name of the Angular module to create moduleName: "my.templates" },
如果你使用Yeoman来支撑你的应用程序,这个配置将工作
plugins: [ 'karma-phantomjs-launcher','karma-jasmine','karma-ng-html2js-preprocessor' ],preprocessors: { 'app/views/*.html': ['ng-html2js'] },ngHtml2JsPreprocessor: { stripPrefix: 'app/',moduleName: 'my.templates' },
步骤2:在测试中使用模块
// my-test.js beforeEach(module("my.templates")); // load new module containing templates
有一个完整的例子,看看这@L_502_6@.它包括一个完整的设置:karma配置,模板和测试。
非卡尔解决方案
如果你不以任何原因使用Karma(我在遗留应用程序中有一个不灵活的构建过程),并且只是在浏览器中测试,我发现你可以通过使用原始XHR获取模板来绕过ngMock的$ httpBackend的接管为真实并将其插入$ templateCache。这个解决方案不那么灵活,但它现在完成了工作。
// my-test.js // Make template available to unit tests without Karma // // Disclaimer: Not using Karma may result in bad karma. beforeEach(inject(function($templateCache) { var directiveTemplate = null; var req = new XMLHttpRequest(); req.onload = function() { directiveTemplate = this.responseText; }; // Note that the relative path may be different from your unit test HTML file. // Using `false` as the third parameter to open() makes the operation synchronous. // Gentle reminder that boolean parameters are not the best API choice. req.open("get","../../partials/directiveTemplate.html",false); req.send(); $templateCache.put("partials/directiveTemplate.html",directiveTemplate); }));
真的,虽然。使用Karma.它需要一些工作来设置,但它允许您运行所有的测试,在多个浏览器中,从命令行。因此,您可以将其作为持续集成系统的一部分,和/或您可以使其成为您的编辑器的快捷键。比alt-tab-refresh-ad-infinitum好多了。