Jasmine用templateUrltestingAngularJS指令

我正在用Jasmine编写AngularJS的指令testing,并使用templateUrl: https : //gist.github.com/tanepiper/62bd10125e8408def5cc

但是,当我运行testing时,我得到了错误包括在要点:

Error: Unexpected request: GET views/currency-select.html 

从我在文档中读到的东西,我认为我正确地做了这件事,但似乎并不是这样 – 我在这里错过了什么?

谢谢

如果您使用的是ngMockE2E或ngMock:

所有的 HTTP请求都使用您指定的规则在本地进行处理,并且没有任何内容被传递给服 由于模板是通过HTTP请求的,它们也是在本地处理的。 由于您的应用程序尝试连接到views/currency-select.html时未指定任何操作,因此它会告诉您不知道如何处理它。 你可以很容易地告诉ngMockE2E传递你的模板请求:

 $httpBackend.whenGET('views/currency-select.html').passThrough(); 

请记住,如果您愿意,还可以在路由path中使用正则expression式来遍历所有模板。

文档更详细地讨论这个: http : //docs.angularjs.org/api/ngMockE2E.$httpBackend

否则使用这个:

您将需要使用$injector来访问新的后端。 从链接的文档:

 var $httpBackend; beforeEach(inject(function($injector) { $httpBackend = $injector.get('$httpBackend'); $httpBackend.whenGET('views/currency-select.html').respond(200, ''); })); 

Karma的方式是将模板htmldynamic加载到$ templateCache中。 您可以使用html2js业务预处理器,如此处所述

这可以归结为在conf.js文件中添加模板“ .html”到你的文件以及预处理器= {' .html':'html2js'};

并使用

 beforeEach(module('..')); beforeEach(module('...html', '...html')); 

进入你的jstesting文件

如果这是一个unit testing,您将无法访问$httpBackend.passthrough() 。 这只在ngMock2E2中可用,用于端到端testing。 我同意涉及ng-html2js (曾经被命名为html2js)的答案,但是我想在这里提供一个完整的解决scheme。

为了呈现您的指令,Angular使用$http.get()templateUrl获取templateUrl 。 因为这是unit testing和angular-mocks加载, angular-mocks截获对$http.get()的调用,并给你Unexpected request: GET错误。 你可以尝试通过传递这个方法来find方法,但是使用angular的$templateCache来预装你的模板要简单得多。 这样, $http.get()甚至不会是一个问题。

这就是ng-html2js预处理器为你做的。 为了使其工作,首先安装它:

 $ npm install karma-ng-html2js-preprocessor --save-dev 

然后通过添加/更新您的karma.conf.js的以下字段进行karma.conf.js

 { files: [ // // all your other files // //your htmp templates, assuming they're all under the templates dir 'templates/**/*.html' ], preprocessors: { // // your other preprocessors // // // tell karma to use the ng-html2js preprocessor "templates/**/*.html": "ng-html2js" }, ngHtml2JsPreprocessor: { // // Make up a module name to contain your templates. // We will use this name in the jasmine test code. // For advanced configs, see https://github.com/karma-runner/karma-ng-html2js-preprocessor moduleName: 'test-templates', } } 

最后,在你的testing代码中,使用你刚刚创build的test-templates模块。 只需将test-templates添加到通常在beforeEachbeforeEach的模块调用中,如下所示:

 beforeEach(module('myapp', 'test-templates')); 

应该从这里顺利航行出去。 为了更深入的了解这个和其他的指令testing场景,看看这个post

你也许可以从注入器获得$templatecache然后做类似的事情

 $templateCache.put("views/currency-select.html","<div.....>"); 

在哪里代替<div.....>你会把你的模板。

之后,你设置你的指令,它应该工作得很好!

如果仍然无效,请使用fiddler查看由htmltojs处理器dynamic生成的js文件的内容,并检查模板文件的path。

应该是这样的

 angular.module('app/templates/yourtemplate.html', []).run(function($templateCache) { $templateCache.put('app/templates/yourtemplate.html', 

就我而言,这与我在导致问题的实际指示方面并不一样。

在所有的地方使用templateURL完全相同。

根据要求,将评论转换为答案。


对于想要在Yeoman应用中使用@Lior的答案的人:

有时模板在karmaconfiguration中被引用,结果是ng-html2js生成的模块名称与指令定义中指定为templateUrl的值不匹配。
您将需要调整生成的模块名称以匹配templateUrl
这些可能会有所帮助:

这个例子是如何testing使用partial作为templateUrl的指令的

 describe('with directive', function(){ var scope, compile, element; beforeEach(module('myApp'));//myApp module beforeEach(inject(function($rootScope, $compile, $templateCache){ scope = $rootScope.$new(); compile = $compile; $templateCache.put('view/url.html', '<ul><li>{{ foo }}</li>' + '<li>{{ bar }}</li>' + '<li>{{ baz }}</li>' + '</ul>'); scope.template = { url: 'view/url.html' }; scope.foo = 'foo'; scope.bar = 'bar'; scope.baz = 'baz'; scope.$digest(); element = compile(angular.element( '<section>' + '<div ng-include="template.url" with="{foo : foo, bar : bar, baz : baz}"></div>' + '<div ng-include="template.url" with=""></div>' + '</section>' ))(scope); scope.$digest(); })); it('should copy scope parameters to ngInclude partial', function(){ var isolateScope = element.find('div').eq(0).scope(); expect(isolateScope.foo).toBeDefined(); expect(isolateScope.bar).toBeDefined(); expect(isolateScope.baz).toBeDefined(); }) }); 

如果您将jasmine-maven-plugin和RequireJS一起使用,则可以使用文本插件将模板内容加载到variables中,然后将其放入模板caching中。

 define(['angular', 'text!path/to/template.html', 'angular-route', 'angular-mocks'], function(ng, directiveTemplate) { "use strict"; describe('Directive TestSuite', function () { beforeEach(inject(function( $templateCache) { $templateCache.put("path/to/template.html", directiveTemplate); })); }); });