Понимание зависимости от инъекций в приложении и тестах в AngularJS

89
3

У меня есть проблема с инъекцией зависимостей (понимание) при тестировании директивы (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');
});

Обе работы, но я не понимаю, какой из них лучше и почему? И почему он работает в моем браузере с самого начала и не работает в моем тесте? В обоих случаях все мои директивы и трекеры вводятся в мою основную декларацию приложения

благодаря

спросил(а) 2014-04-10T13:34:00+04:00 6 лет, 5 месяцев назад
1
Решение
57

Загрузочные модули

Она работает в вашем приложении, поскольку services.httpRequestTracker загружается. вы сделали это, объявив его как зависимость основного модуля приложения (ваш первый фрагмент кода).

Однако, когда вы проверяете вещи, вы хотите высмеять все, что не тестируется, чтобы избежать смещения. В вашем случае, что, если у вас возникла проблема в services.httpRequestTracker? ajaxLoader может быть прекрасным, но ваши тесты не удастся.

Дразнящий

Чтобы издеваться над всем остальным, у вас есть два варианта:

Чтобы использовать зависимость, вам необходимо загрузить модуль с помощью module().

вам придется загружать зависимость, но это может иметь макетную реализацию.

Внедрение зависимости

Включение зависимостей позволяет разделить классы. Для определения зависимостей по имени существует локатор службы. То есть, вы говорите, что атрибут a класса C имеет тип "animal" (строка!). Локатор сервисов в угловом сердечнике находит, какой компонент его реализует. Способ определения этого - поиск загруженных модулей (например, зависимости основного модуля приложения).

Вы не определили это в своей тестовой области (но это не проблема!). Карма использует файл karma.conf, содержащий список файлов для использования. Вы можете использовать этот файл для добавления библиотек или издевательства над компонентами.

С вашей конкретной проблемой:

Директива зависит от httpRequestTracker. Если вы не вводите его там, это не сработает (так хорошо). В вашем тесте вы должны загрузить оба. Вот почему в первый раз он провалился, а второй он сработал. Однако вместо загрузки httpRequestTracker я бы загрузил httpRequestTracker реализацию.

ответил(а) 2014-04-15T12:30:00+04:00 6 лет, 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема