Понимание зависимости от инъекций в приложении и тестах в AngularJS
У меня есть проблема с инъекцией зависимостей (понимание) при тестировании директивы (AjaxLoader отображается только тогда, когда есть ожидающий запрос).
Объявление приложения:
angular.module('app', [
'directives.ajaxLoader',
'services.httpRequestTracker',
[...]
])
Код директивы:
angular.module('directives.ajaxLoader', [])
.directive('ajaxLoader', ['httpRequestTracker',
function(httpRequestTracker) {
return {
templateUrl: 'common/ajaxLoader.tpl.html',
link: function($scope) { // This function can have more parameters after $scope, $element, $attrs, $controller
$scope.hasPendingRequests = function() {
return httpRequestTracker.hasPendingRequests();
};
}
};
}
])
Тестовый код:
describe('ajaxLoader', function() {
beforeEach(function() {
module('directives.ajaxLoader', 'common/ajaxLoader.tpl.html');
});
describe('ajaxLoader directive', function() {});
});
Оттуда моя директива прекрасно работает в браузере, но тесты терпят неудачу с ошибкой, например:
Ошибка: [$ injector: unpr] Неизвестный поставщик: httpRequestTrackerProvider <- httpRequestTracker <- ajaxLoaderDirective
Хорошо, поэтому мне нужно каким-то образом ввести свою зависимость. У меня есть два решения:
- в моей директиве напрямую:
angular.module('directives.ajaxLoader', [
'services.httpRequestTracker'
])
- в моем тестовом коде напрямую:
beforeEach(function() {
module('directives.ajaxLoader', 'common/ajaxLoader.tpl.html', 'services.httpRequestTracker');
});
Обе работы, но я не понимаю, какой из них лучше и почему? И почему он работает в моем браузере с самого начала и не работает в моем тесте? В обоих случаях все мои директивы и трекеры вводятся в мою основную декларацию приложения
благодаря
Загрузочные модули
Она работает в вашем приложении, поскольку services.httpRequestTracker
загружается. вы сделали это, объявив его как зависимость основного модуля приложения (ваш первый фрагмент кода).
Однако, когда вы проверяете вещи, вы хотите высмеять все, что не тестируется, чтобы избежать смещения. В вашем случае, что, если у вас возникла проблема в services.httpRequestTracker
? ajaxLoader
может быть прекрасным, но ваши тесты не удастся.
Дразнящий
Чтобы издеваться над всем остальным, у вас есть два варианта:
- шпионов (например, это http://angular-tips.com/blog/2014/03/introduction-to-unit-test-spies/) использовать инъекцию зависимости для замены компонентов
Чтобы использовать зависимость, вам необходимо загрузить модуль с помощью module()
.
вам придется загружать зависимость, но это может иметь макетную реализацию.
Внедрение зависимости
Включение зависимостей позволяет разделить классы. Для определения зависимостей по имени существует локатор службы. То есть, вы говорите, что атрибут a класса C имеет тип "animal" (строка!). Локатор сервисов в угловом сердечнике находит, какой компонент его реализует. Способ определения этого - поиск загруженных модулей (например, зависимости основного модуля приложения).
Вы не определили это в своей тестовой области (но это не проблема!). Карма использует файл karma.conf
, содержащий список файлов для использования. Вы можете использовать этот файл для добавления библиотек или издевательства над компонентами.
С вашей конкретной проблемой:
Директива зависит от httpRequestTracker
. Если вы не вводите его там, это не сработает (так хорошо). В вашем тесте вы должны загрузить оба. Вот почему в первый раз он провалился, а второй он сработал. Однако вместо загрузки httpRequestTracker
я бы загрузил httpRequestTracker
реализацию.
- Вопросы
- Karma-runner
- Понимание зависимости от инъекций в приложении и тестах в AngularJS