Жасмин проверяет директивы AngularJS с помощью templateUrl
Я пишу тесты директив для AngularJS с Jasmine и использую templateUrl с ними: https://gist.github.com/tanepiper/62bd10125e8408def5cc
Однако, когда я запускаю тест, я получаю сообщение об ошибке, включенное в суть:
Error: Unexpected request: GET views/currency-select.html
Из того, что я прочитал в документах, я думал, что делал все правильно, но это не так - что мне здесь не хватает?
Спасибо
8 ответов
Если вы используете ngMockE2E или ngMock:
все HTTP-запросы обрабатываются локально с использованием указанных вами правил, и ни один из них не передается на сервер. Поскольку шаблоны запрашиваются через HTTP, они также обрабатываются локально. Поскольку вы не указали, что делать, когда ваше приложение пытается подключиться к views/currency-select.html
, он говорит вам, что не знает, как справиться с этим. Вы можете легко сказать ngMockE2E передать ваш шаблонный запрос:
$httpBackend.whenGET('views/currency-select.html').passThrough();
Помните, что вы также можете использовать регулярные выражения в путях маршрутизации для прохождения всех шаблонов, если хотите.
Документы обсуждают это более подробно: 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, '');
}));
Карма способ динамически загружать HTML-шаблон в $ templateCache. вы можете просто использовать препроцессор html2js karma, как описано здесь
это сводится к добавлению шаблонов '.html' к вашим файлам в файле conf.js, а также к препроцессорам = {'.html': 'html2js'};
и использовать
beforeEach(module('..'));
beforeEach(module('...html', '...html'));
в ваш файл JS тестирования
Если это юнит-тест, у вас не будет доступа к $httpBackend.passthrough()
, Это доступно только в ngMock2E2 для сквозного тестирования. Я согласен с ответами, касающимися ng-html2js
(раньше назывался html2js), но я хотел бы остановиться на них, чтобы предоставить полное решение здесь.
Чтобы сделать вашу директиву, Angular использует $http.get()
чтобы получить ваш шаблон из templateUrl
, Потому что это юнит-тестирование и angular-mocks
загружен, angular-mocks
перехватывает вызов $http.get()
и дать вам Unexpected request: GET
ошибка. Вы можете попытаться найти способ обойти это, но гораздо проще просто использовать угловые $templateCache
предварительно загрузить ваши шаблоны. Сюда, $http.get()
не будет даже проблемой.
Вот что делает для вас препроцессор ng-html2js. Чтобы заставить его работать, сначала установите его:
$ npm install karma-ng-html2js-preprocessor --save-dev
Затем настройте его, добавив / обновив следующие поля в вашем 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',
}
}
Наконец, в вашем тестовом коде используйте test-templates
модуль, который вы только что создали. Просто добавь test-templates
на вызов модуля, который вы обычно делаете в beforeEach
, как это:
beforeEach(module('myapp', 'test-templates'));
Это должно быть гладкое плавание с этого момента. Для более глубокого изучения этого и других сценариев тестирования директив ознакомьтесь с этой статьей.
Вы могли бы, возможно, получить $templatecache
от инжектора, а затем сделать что-то вроде
$templateCache.put("views/currency-select.html","<div.....>");
где вместо <div.....>
вы бы положили свой шаблон.
После этого вы устанавливаете свою директиву, и она должна работать просто отлично!
Если это все еще не работает, используйте fiddler, чтобы просмотреть содержимое файла js, динамически сгенерированного процессором htmltojs, и проверьте путь к файлу шаблона.
Должно быть как то так
angular.module('app/templates/yourtemplate.html', []).run(function($templateCache) {
$templateCache.put('app/templates/yourtemplate.html',
В моем случае это было не то, что было в моей настоящей директиве, которая вызывала проблему.
То, что templateURL абсолютно одинаков во всех местах, помогло мне.
По запросу конвертируем комментарий в ответ.
Для людей, которые хотят использовать ответ @Lior в приложениях Yeoman:
Иногда способ ссылки на шаблоны в конфигурации karma и, следовательно, - имена модулей, произведенных ng-html2js
не соответствуют значениям, указанным как templateUrl
s в определениях директивы.
Вам нужно будет настроить сгенерированные имена модулей, чтобы они соответствовали templateUrl
s.
Это может быть полезно:
Это пример того, как проверить директиву, которая использует частичное в качестве 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, вы можете использовать текстовый плагин, чтобы загрузить содержимое шаблона в переменную и затем поместить его в кэш шаблона.
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);
}));
});
});