单元测试与templateUrl的AngularJS指令

前端之家收集整理的这篇文章主要介绍了单元测试与templateUrl的AngularJS指令前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个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');
            });

        });
    });
});

当我运行这在我的Jasmine规格错误,我得到以下错误

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好多了。

猜你在找的Angularjs相关文章