使用AngularJS。
有一个指令。
指令定义templateUrl
。
指令需要单元测试。
目前使用Jasmine进行单元测试。
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需要按原样加载
无法使用respond
发布于 2013-03-06 02:32:23
我最终所做的就是获取模板缓存并将视图放入其中。我无法控制不使用ngMock,事实证明:
beforeEach(inject(function(_$rootScope_, _$compile_, $templateCache) {
$scope = _$rootScope_;
$compile = _$compile_;
$templateCache.put('path/to/template.html', '<div>Here goes the template</div>');
}));
发布于 2013-08-22 05:48:17
你说得对,它与ngMock有关。为每个角度测试自动加载ngMock模块,并初始化模拟$httpBackend
以处理$http
服务的任何使用,包括模板获取。模板系统试图通过$http
加载模板,但它变成了对模拟的“意外请求”。
您需要的是一种无需使用$http
就可以将模板预加载到$templateCache
中的方法,这样当Angular请求它们时,它们就已经可用了。
首选解决方案: 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
有关完整的示例,请查看此canonical example from Angular test guru Vojta Jina。它包括一个完整的设置: karma配置、模板和测试。
非因果报应解决方案
如果您出于某种原因不使用Karma (我在遗留应用程序中有一个不灵活的构建过程),并且只是在浏览器中测试,我发现您可以通过使用原始的XHR来实际获取模板并将其插入到$templateCache
中来绕过ngMock对$httpBackend
的接管。这种解决方案的灵活性要低得多,但它可以暂时完成工作。
// 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好多了。
发布于 2014-09-04 19:06:02
我的解决方案是:
test/karma-utils.js
function httpGetSync(filePath) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/base/app/" + filePath, false);
xhr.send();
return xhr.responseText;
}
function preloadTemplate(path) {
return inject(function ($templateCache) {
var response = httpGetSync(path);
$templateCache.put(path, response);
});
}
karma.config.js
files: [
//(...)
'test/karma-utils.js',
'test/mock/**/*.js',
'test/spec/**/*.js'
],
测试:
'use strict';
describe('Directive: gowiliEvent', function () {
// load the directive's module
beforeEach(module('frontendSrcApp'));
var element,
scope;
beforeEach(preloadTemplate('views/directives/event.html'));
beforeEach(inject(function ($rootScope) {
scope = $rootScope.$new();
}));
it('should exist', inject(function ($compile) {
element = angular.element('<event></-event>');
element = $compile(element)(scope);
scope.$digest();
expect(element.html()).toContain('div');
}));
});
https://stackoverflow.com/questions/15214760
复制相似问题