Jasmine тестирует директивы 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 pre-processor, как объяснил здесь
это сводится к добавлению шаблонов '.html ' к вашим файлам в конф.файл 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
ошибка. Вы можете попытаться найти способы пройти мимо этого, но гораздо проще просто использовать angular$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 в старшина приложения:
иногда способ ссылки на шаблоны в конфигурации karma и, следовательно, - имена модулей, созданных
ng-html2js
не соответствует значениям, указанным какtemplateUrl
s в определениях директив.
Вам нужно будет настроить сгенерированные имена модулей, чтобы соответствоватьtemplateUrl
s.
Это может быть полезно:
Это пример того, как проверить директиву, которая использует 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 вы можете использовать текст плагин загрузить шаблон в переменную, а затем поместить его в кэш шаблона.
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); })); }); });