У меня есть директива AngularJS с templateUrl
определенным файлом. Я пытаюсь провести модульное тестирование с помощью Jasmine.
Мой жасмин JavaScript выглядит следующим образом , в соответствии с рекомендацией этого :
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
. Я считаю, что это может быть связано с использованием ngMock вместо ngMockE2E . Если это виноват, как мне использовать последнее вместо первого?
Заранее спасибо!
.passThrough();
таким образом, но, судя по документации, вы пробовали что-то вроде:$httpBackend.expectGET('path/to/template.html'); // do action here $httpBackend.flush();
Я думаю, что это лучше подходит для вашего использования - вы не хотите перехватывать запрос, т.е.whenGet()
вместо этого проверять, что он отправлен, а затем на самом деле Отправь это?expectGET
отправляет запросы ... по крайней мере, из коробки. В документации/auth.py
приводится их пример с$httpBackend.when
префиксом$httpBackend.expectGET
и$httpBackend.flush
вызовами.expectGet
просто проверяется, была ли попытка запроса.$httpBackend
макету, чтобы он действительно использовал URL-адрес, указанный в директиве,templateUrl
и получил его. ДумалpassThrough
сделаю это. Вы знаете другой способ сделать это?Ответы:
Вы правы, что это связано с ngMock. Модуль ngMock автоматически загружается для каждого теста Angular и инициализирует макет
$httpBackend
для обработки любого использования$http
службы, включая выборку шаблона. Система шаблонов пытается загрузить шаблон,$http
и это становится «неожиданным запросом» к макету.Вам нужен способ предварительной загрузки шаблонов в,
$templateCache
чтобы они уже были доступны, когда Angular их запросит, без использования$http
.Предпочтительное решение: карма
Если вы используете Karma для запуска своих тестов (а вы должны это делать), вы можете настроить его для загрузки шаблонов за вас с помощью препроцессора ng-html2js . Ng-html2js считывает указанные файлы HTML и преобразует их в модуль Angular, который предварительно загружает
$templateCache
.Шаг 1. Включите и настройте препроцессор в вашем
karma.conf.js
Если вы используете Yeoman для построения своего приложения, эта конфигурация будет работать
Шаг 2. Используйте модуль в своих тестах
Чтобы получить полный пример, посмотрите этот канонический пример от гуру тестирования Angular Войты Джины. . Включает в себя всю настройку: конфиг кармы, шаблоны и тесты.
Решение без кармы
Если вы не используете Karma по какой-либо причине (у меня был негибкий процесс сборки в устаревшем приложении) и вы просто тестируете в браузере, я обнаружил, что вы можете обойти захват ngMock,
$httpBackend
используя необработанный XHR для получения шаблона для реального и вставьте его в$templateCache
. Это решение гораздо менее гибкое, но на данный момент оно выполняет свою работу.Если серьезно. Используйте карму . Настройка требует небольшой работы, но позволяет запускать все тесты одновременно в нескольких браузерах из командной строки. Таким образом, вы можете использовать его как часть вашей системы непрерывной интеграции, и / или вы можете сделать его сочетанием клавиш в редакторе. Намного лучше, чем alt-tab-refresh-ad-infinitum.
источник
preprocessors
шаблон файла (например"path/to/templates/**/*.html"
) вfiles
раздел вkarma.conf.js
.false
параметр дляopen
вызова XHR, чтобы сделать его синхронным. Если вы этого не сделаете, выполнение будет продолжено и начнется выполнение ваших тестов без загрузки шаблона. Это возвращает вас к той же проблеме: 1) Запрос на шаблон уходит. 2) Тест начинает выполняться. 3) Тест компилирует директиву, а шаблон все еще не загружен. 4) Angular запрашивает шаблон через свой$http
сервис, который имитируется. 5) Мок-$http
сервис жалуется: «неожиданный запрос».npm install --save-dev karma-ng-html2js-preprocessor
) и добавить его в раздел плагинов вашегоkarma.conf.js
, согласно stackoverflow.com/a/19077966/859631 .В итоге я получил кеш шаблонов и поместил туда представление. У меня нет контроля над тем, чтобы не использовать ngMock, оказывается:
источник
Эту начальную проблему можно решить, добавив следующее:
Это потому, что он пытается найти $ httpBackend в модуле ngMock по умолчанию, а он не заполнен.
источник
Решение, которое я нашел, требует jasmine-jquery.js и прокси-сервера.
Я выполнил следующие шаги:
добавьте jasmine-jquery.js в свои файлы
добавьте прокси-сервер, который будет обслуживать ваши светильники
В вашей спецификации
описать ('MySpec', function () {var $ scope, template; jasmine.getFixtures (). fixturesPath = 'public / partials /'; // настраиваемый путь, чтобы вы могли обслуживать реальный шаблон, который используете в приложении beforeEach (function () {шаблон = angular.element ('');
});
Запустите сервер в корневом каталоге вашего приложения
python -m SimpleHTTPServer 3502
Запустите карму.
Мне потребовалось время, чтобы понять это, мне пришлось искать много сообщений, я думаю, что документация по этому поводу должна быть более ясной, поскольку это такой важный вопрос.
источник
localhost/base/specs
и добавлением прокси-сервера сpython -m SimpleHTTPServer 3502
исправленным запуском. Вы сэр гений!Мое решение:
test/karma-utils.js
:karma.config.js
:тест:
источник
static
, например,beforeEach(preloadTemplate(static_url +'seed/partials/beChartDropdown.html'));
спасибо!Если вы используете Grunt, вы можете использовать шаблоны grunt-angular. Он загружает ваши шаблоны в templateCache и прозрачен для вашей конфигурации спецификаций.
Мой образец конфигурации:
источник
Я решил ту же проблему несколько иначе, чем выбранное решение.
Сначала я установил и настроил плагин ng-html2js для кармы. В файле karma.conf.js:
Затем я загрузил модуль, созданный в beforeEach. В вашем файле Spec.js:
Затем я использовал $ templateCache.get, чтобы сохранить его в переменной. В вашем файле Spec.js:
Наконец, я проверил это таким образом. В вашем файле Spec.js:
источник
Чтобы загрузить шаблон html динамически в $ templateCache, вы можете просто использовать препроцессор html2js karma, как описано здесь.
это сводится к добавлению шаблонов ' .html' в ваши файлы в файле conf.js, а также preprocessors = {' .html': 'html2js'};
и использовать
в ваш файл тестирования js
источник
Uncaught SyntaxError: Unexpected token <
если вы используете Карму, подумайте об использовании karma-ng-html2js-preprocessor для предварительной компиляции ваших внешних HTML-шаблонов и избегайте того, чтобы Angular пытался HTTP GET во время выполнения теста. Я боролся с этим в течение нескольких наших - в моем случае частичные пути templateUrl разрешались во время обычного выполнения приложения, но не во время тестов - из-за различий в структурах приложений и тестовых каталогов.
источник
Если вы используете jasmine-maven-plugin вместе с RequireJS, вы можете использовать текстовый плагин для загрузки содержимого шаблона в переменную, а затем поместить его в кеш шаблона.
источник
Если вы используете requirejs в своих тестах, вы можете использовать плагин 'text' для извлечения шаблона html и помещения его в $ templateCache.
источник
Я решил эту проблему, скомпилировав все шаблоны в templatecache. Я использую gulp, вы можете найти подобное решение и для grunt. Мои templateUrls в директивах, модальные окна выглядят как
Добавьте новый пакет npm в мой package.json
"gulp-angular-templatecache": "1.*"
В файле gulp добавьте templatecache и новую задачу:
var templateCache = require('gulp-angular-templatecache'); ... ... gulp.task('compileTemplates', function () { gulp.src([ './app/templates/**/*.html' ]).pipe(templateCache('templates.js', { transformUrl: function (url) { return '/templates/' + url; } })) .pipe(gulp.dest('wwwroot/assets/js')); });
Добавьте все js файлы в index.html
<script src="/assets/js/lib.js"></script> <script src="/assets/js/app.js"></script> <script src="/assets/js/templates.js"></script>
Наслаждайтесь!
источник