Как выполнить модульное тестирование сервиса / фабрики AngularJS
Я уже некоторое время занимаюсь разработкой с использованием AngularJS, и то, что я пишу, работает, но я знаю, что пришел к точке, где я хотел бы запустить модульные тесты для своего кода AngularJS.
Я создал очень простой сервис, который будет вставлять таблицу стилей на страницу, см. Пример кода ниже:
var OfficeSuiteStylesheetInjectorModule = angular.module('OfficeSuiteStylesheetInjectorModule', []);
OfficeSuiteStylesheetInjectorModule.factory('stylesheetInjectorService', ['$q', function($q) {
// Returns the service itself.
return {
inject: function(id, uri) {
var deferred = $q.defer();
// Embed the stylesheet into the page, but only when it's non-existing.
if (!angular.element('#' + id).length) {
var link = StylesheetFactory.Create(id, uri);
{
link.onload = deferred.resolve;
angular.element('head').append(link);
}
return deferred.promise;
}
}
}
}]);
Это не большой сервис, это просто зависит от $q
для обещаний, чтобы я мог запустить дополнительную логику, когда таблица стилей была встроена в страницу.
Теперь я использую Jasmine (я новичок в этом) для тестирования своего кода JavaScript, и я хотел бы протестировать этот модуль.
У меня есть скелет:
// Tests for the angular 'StylesheetInjectorService'.
describe('StylesheetInjectorService', function() {
var stylesheetInjectorService = {};
// This code is executed before every test.
beforeEach(function() {
// Tells jamine that the module we're working on is the 'OfficeSuiteStylesheetInjectorModule'.
angular.module('OfficeSuiteStylesheetInjectorModule');
});
// Ensures that it injects a stylesheet element into the page.
it('Should inject a stylesheet element into the page.', function() {
// How to test here that the stylesheet is injected?
});
});
});
Как я могу добавить сервис на страницу и обеспечить загрузку таблицы стилей?
Редактировать: Сервис загрузки теперь работает:
beforeEach(module('OfficeSuiteStylesheetInjectorModule'));
// This code is executed before every test.
beforeEach(function() {
// Inject the required dependencies into the page.
inject(function($injector) {
stylesheetInjectorService = $injector.get('stylesheetInjectorService');
});
});
Однако тот же вопрос остается открытым. Как проверить, была ли таблица стилей встроена в страницу?
Любая помощь высоко ценится.
С уважением
2 ответа
Написать спецификацию для прикрепления таблицы стилей к angular.element('head')
Я бы немного изменил логику, чтобы привязать его к $document.head
,
Если вы не хотите этого делать, я бы порекомендовал вам изменить свой сервис на
directive
видя, как внедрение элемента сценария, манипулирование DOM. Таким образом, вы убили бы двух зайцев одним выстрелом$compile
проверить вашу директиву (которая позволит вам скомпилироватьhead
элемент для загрузки). Но пока это немного "сверх".
Реализация:
if (!angular.element('#' + id).length) {
var link = StylesheetFactory.Create(id, uri);
link.onload = deferred.resolve;
$document.head.append(link);
return deferred.promise;
}
}
beforeEach:
/**
* Sorry, this was previously $location which was just
* such a silly mistake.
*/
var $timeout;
beforeEach(function () {
inject(function ($injector) {
$timeout = $injector.get('$timeout');
});
});
Это:
it('attaches the stylesheet to $document.head', function () {
styleSheetInjectorService.inject('someId', '/path/to/some/stylesheet');
$timeout.flush(); // flush promises
expect(angular.element($document.head).lastChild[0].nodeName).to.eq('LINK');
});
Что-то в этом роде должно заставить вас работать. Не забывайте, что в спецификации, которую я написал, используются утверждения стиля chai # автомата и тестовый фреймворк mocha. Измените синтаксис, чтобы он соответствовал Jasmine, если вы хотите скопировать и вставить.
У меня было это сомнение некоторое время назад. Чтобы внедрить ваши контроллеры и сервисы в ваши тесты, вам нужно использовать инструмент под названием Angular Mocks. Вот официальное упоминание об этом.
Я полагаю, вы используете его вместе со средой Кармы.
Вот отличное руководство по началу работы:
https://www.airpair.com/angularjs/posts/unit-testing-angularjs-applications
Этот другой предназначен для Ionic Framework, но все еще может применяться в вашем случае
Надеюсь, это поможет.