Jasmine使用templateUrl测试AngularJS指令

Tan*_*per 70 unit-testing jasmine angularjs angularjs-directive

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

但是,当我运行测试时,我得到了gist中包含的错误:

Error: Unexpected request: GET views/currency-select.html
Run Code Online (Sandbox Code Playgroud)

从我在文档中看到的,我认为我正确地做了这个,但它似乎不是这样 - 我在这里错过了什么?

谢谢

Jos*_*ler 70

如果您使用的是ngMockE2E或ngMock:

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

$httpBackend.whenGET('views/currency-select.html').passThrough();
Run Code Online (Sandbox Code Playgroud)

请记住,如果您愿意,还可以在路由路径中使用正则表达式来传递所有模板.

文档更详细地讨论了这个问题: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, '');
}));
Run Code Online (Sandbox Code Playgroud)

  • $ httpBackend Mock中没有passThrough()方法.它在文档中说得对.http://docs.angularjs.org/api/ngMock/service/$httpBackend这就是为什么你的功能不可用错误.现在,如果你想在前端和单元测试中模拟这个,你可以使用passThrough方法 - 只是不在单元测试中...... (4认同)
  • @StenMuchow我的答案和@ tanepiper的问题不适用于`ngMock`模块,而是[`ngMockE2E`](http://docs.angularjs.org/api/ngMockE2E/service/$httpBackend)模块,**支持`passThrough()`.通常,在单元测试期间不会使用它,因为单元测试不需要任何HTTP请求(如模板),但是如果它们执行并且构建不编译它们,则可以使用E2E后端. (3认同)
  • 嗯,我已经尝试了这个,但似乎在我注入之后,passThrough不能用作函数:TypeError:'undefined'不是函数(评估'$ httpBackend.when('GET','views/currency-select.html').passThrough()')我还包括beforeEach(module('ngMockE2E')); 在我的文件的顶部,它返回到原始错误 (2认同)

Lio*_*ior 20

Karma方式是将模板html动态加载到$ templateCache中.你可以只使用html2js因缘预处理器,如解释在这里

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

并使用

beforeEach(module('..'));

beforeEach(module('...html', '...html'));
Run Code Online (Sandbox Code Playgroud)

进入你的js测试文件

  • 以下是templateCache-way如何工作的相当好的解释:http://www.portlandwebworks.com/blog/testing-angularjs-directives-handling-external-templates.请注意,该博客讲述了一个相当旧版本的Karma,所以今天你需要使用ng-html2js而不是html2js来预处理模板到js. (3认同)

las*_*ood 6

如果这是单元测试,您将无法访问$httpBackend.passthrough().这仅适用于ngMock2E2,用于端到端测试.我同意涉及的答案ng-html2js(以前名为html2js),但我想扩展它们以提供完整的解决方案.

要呈现您的指令,Angular用于$http.get()从中获取模板templateUrl.因为这是单元测试并angular-mocks加载,所以angular-mocks拦截调用$http.get()并给出Unexpected request: GET错误.您可以尝试通过此方法找到方法,但使用angular's $templateCache来预加载模板要简单得多.这样,$http.get()甚至不会成为一个问题.

这就是ng-html2js预处理器为您所做的事情.要使它工作,首先安装它:

$ npm install karma-ng-html2js-preprocessor --save-dev
Run Code Online (Sandbox Code Playgroud)

然后通过添加/更新您的以下字段来配置它 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',
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,在您的测试代码中,使用test-templates您刚刚创建的模块.只需添加test-templates您通常进行的模块调用beforeEach,如下所示:

beforeEach(module('myapp', 'test-templates'));
Run Code Online (Sandbox Code Playgroud)

它应该从这里开始顺利航行.有关此和其他指令测试方案的更深入了解,请查看此文章


gan*_*raj 5

你也许可以$templatecache从注射器中取出然后做类似的事情

$templateCache.put("views/currency-select.html","<div.....>");
Run Code Online (Sandbox Code Playgroud)

在哪里代替<div.....>你将放置你的模板.

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

  • 我使用$ httpBackend做$ httpBackend.when('GET','views/currency-select.html').回复('<select ng-options ="currency.name for currency in currency"ng-model = "selected_currency"> </选择>'); - 但它有点打败DRY - 我希望它加载我的模板,而不是再次在代码中重复它们. (6认同)