E2E mock $ httpBackend на самом деле не пропускает для меня

Хотя я считаю, что следую инструкциям здесь для настройки $ httpBackend для передачи выбранных запросов на сервер, это не работает для меня.

Вот Plunkr с неудачным тестом, который показывает, что я делаю, и объясняет в комментариях, что, кажется, идет не так.

Мой spelunking предполагает, что по какой-то причине mock $httpBackend не имеет внутренней копии реального $httpBackend так что, когда придет время пройти через запрос XHR, он передает его вместо mock $httpBackend . Второй вызов вызывает исключение, поскольку он не знает, что делать с запросом.

Ответ на dtabuenc

Я с благодарностью вспоминаю ваш пост на промежуточном тестировании. Вы определяете важный диапазон интеграционных тестов, который находится между тестированием unit- и E2E. Я стою на этой средней земле.

Я не думаю, что ты вообще злой. Ваш ответ вполне разумный … или было бы разумно, если бы это не противоречило тексту « API-ссылки / ngMockE2E / $ httpBackend ». Я цитирую:

Эта реализация может использоваться для ответа статическими или динамическими ответами через api и его ярлыки ( whenGET , whenPOST и т. Д.) И необязательно передавать запросы на реальный $httpBackend для конкретных запросов (например, для взаимодействия с определенным удаленным apis или для извлечения шаблоны с веб-сервера)

[I] n сценарий сквозного тестирования или сценарий, когда приложение разрабатывается с заменой реального back-файла api на макет , часто желательно, чтобы определенная категория запросов обходила макет и выдавала настоящий http request …. Чтобы настроить бэкэнд с таким поведением, используйте passThrough запроса passThrough когда вместо respond . [emphasis mine].

В документации не говорится об использовании E2E $httpBackend в среде Jasmine. Я не могу придумать причины, чтобы исключить его. Если есть такая причина, они должны четко заявить об этом. Серьезно, кто читает о макетном компоненте и не ожидает его использования в тестовой среде?

« Пропустить запросы к реальному $httpBackend для конкретных запросов, например, взаимодействовать с определенным удаленным apis », именно то, что я намереваюсь сделать. Что они могут иметь в виду под «реальным $ httpBackend», кроме не-макетной версии этого компонента?

Я не понимаю ваших утверждений о том, что

Модуль ngMocksE2E предназначен для использования на стороне сервера, где выполняется фактическое угловое приложение.

Слово «сервер» отображается ровно 3 раза на этой странице, а не один раз, предполагая, что любой код приложения будет выполняться на «сервере». Я не знаю, что вы подразумеваете под «фактическим угловым приложением», выполняющимся на «стороне сервера».

В документации совершенно ясно, что E2E $httpBackend не ограничивается тестированием E2E. Это также относится к « сценарию, когда приложение разрабатывается с заменой реального бэкэнда api на макет ».

Это всего лишь в двух шагах от моего сценария, в котором приложение тестируется с помощью реального бэкэнда api ».

В моих сценариях SUT обращается к компоненту, который извлекает данные с сервера. Мои тесты существуют для проверки того, что этот зависимый компонент успешно выполняет такие запросы реального бэкэнд и будет получать или сохранять данные ожидаемым образом. Это интеграционный тест, который не может быть удовлетворен надлежащим образом, издеваясь над поведением бэкэнд.

Конечно, я могу протестировать (и сделать тест) с ложными ответами XHR, что способность компонента правильно реагировать на то, что я предсказываю, будет поведением бэкэнда. Это не то же самое, что проверка того, что компонент отвечает на фактическое поведение бэкэнда … что может измениться по мере того, как приложение развивается и отходит от посмеиваемых ответов каким-то значительным образом.

Для этой цели я бы подумал о том, чтобы использовать ваш тестер на полпути, если я понял, как поменять его на код кода SUT. Я не. Я думаю, что компонент, создающий запросы ngMidwayTester недоступен вашему ngMidwayTester . Но я знаю, как замять реального помощника XHR в конвейере, если мне нужно.

Здесь я сейчас стою .

Либо кто-то может показать, как заставить $httpBackend передавать определенные запросы на сервер – как $httpBackend документация, – или я сам passThrough реализацию passThrough на passThrough реализацию passThrough .

Я предпочитаю первый вариант. Если перейти ко второму, я предложу ссылку на него здесь для других, которые разделяют мои потребности и мою интерпретацию документации API.

Есть 3-й путь, который я пропускаю?

4 Solutions collect form web for “E2E mock $ httpBackend на самом деле не пропускает для меня”

Ниже приведено объяснение цели $httpBackend которая находится в модуле ngMockE2E .

Модуль ngMockE2E просто не разработан и не предназначен для использования в спецификации jasmineа.

При проведении сквозного тестирования есть две стороны теста. Один из них – это угловое приложение, которое тестируется, другое – код углового сценария, который находится в спецификации Jasmine.

В тестах E2E нет углового модуля, или ng-mocks, или чего-либо, связанного с угловым на стороне jasmineов (кроме сценария).

Модуль ngMocksE2E предназначен для использования на стороне сервера, где выполняется фактическое угловое приложение. Основная цель – дать нам возможность предварительно реагировать на запросы, чтобы тестирование уровня интеграции на уровне интеграции могло происходить гораздо быстрее, чем если бы каждая страница действительно отправлялась на сервер для JSON.

При использовании jasmineа вместе с ng-mocks угловая всегда будет заменять $ httpBackend макетным файлом. При добавлении модуля ngMocksE2E он не сможет получить какой-либо «настоящий» $httpBackend и, как вы уже узнали, будет просто обманывать макет и делегировать его на прохождение.

Казалось бы, тип теста, который вы пытаетесь написать, – это тест, который не тестирует интеграцию пользовательского интерфейса, а проверяет интеграцию с javascript и сервером приложения.

Это совершенно законный стиль тестирования (в некотором смысле это называется «midwayTesting» в угловом сообществе). Ваша проблема в том, что вы используете неправильный инструмент.

Я бы посмотрел на это:

https://github.com/yearofmoo/ngMidwayTester

Что вы использовали бы вместо угловых-mocks и angular.module (), чтобы облегчить те тесты, которые я предполагаю, что вы хотите сделать.

Вы можете прочитать больше об этом здесь:

http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html

(извинения, если вы уже были связаны там)

EDIT: (Чтобы рассмотреть дополнительные комментарии)

У вас настоящая говядина, так как в документации не ясно, что ngMockE2E нельзя использовать на стороне клиента (то есть карма / jasmine) для сквозной установки тестирования. Неразумно интерпретировать такие вещи, как вы их истолковали, но это не меняет того факта, что толкование неверно.

NgMockE2E будет проходить через запросы, если они будут указаны при использовании на стороне сервера приложения, а не на стороне клиента. Это означает, что вы все равно можете пройти через определенные запросы, которые сложно издеваться над заранее подготовленными ответами. То, что я подразумеваю под клиентом и на стороне сервера, – это то, что при сквозном тестировании есть два конца. У вас есть приложение для тестирования, которое обслуживается стандартным сервером приложений, и у вас есть тестовый код, который управляет приложением, обычно выполняемым в карме или другом тестовом бегуне, которое использует стандартные HTTP-запросы для связи с приложением, которое выполняется в другой процесс.

Если вы посмотрите на документацию и как настроить ngMockE2E вы заметите, что Jasmine не упоминается, а инструкции для настройки в реальном угловом приложении:

 myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']); myAppDev.run(function($httpBackend) { phones = [{name: 'phone1'}, {name: 'phone2'}]; // returns the current list of phones $httpBackend.whenGET('/phones').respond(phones); // adds a new phone to the phones array $httpBackend.whenPOST('/phones').respond(function(method, url, data) { phones.push(angular.fromJson(data)); }); $httpBackend.whenGET(/^\/templates\//).passThrough(); //... }); 

Как вы можете видеть в этом примере, они издеваются над всеми инструкциями данных JSON, позволяя тем самым получать шаблоны с сервера.

Чтобы использовать его из jasmineа, настройка была бы совсем другой, используя angular.mock.module('ngMockE2E') а затем установив $httpBackend.whenGET() в beforeEach() а не в module.run() ,

Что касается ngMidwayTester я ngMidwayTester вас, я считаю, что на самом деле это было бы совместимо с ngMockE2E . По сути ngMidwayTester заменяет angular.mock.module() и angular.mock.module() своими собственными реализациями. Поэтому вы можете использовать его так:

 beforeEach(function(){ tester = ngMidwayTester('app', 'ngMockE2E'); $http = tester.inject('$http'); $httpBackend = tester.inject('$httpBackend'); $rootScope = tester.inject('$rootScope'); }); 

Это должно работать, потому что вы больше не используете модуль ngMock (который всегда включается, когда вы используете angular.mock.module() ). Все должно работать точно так же, как вы хотите, чтобы они использовали ngMidwayTester .

Я наткнулся на ту же проблему, но вместо того, чтобы внедрять богатый API или заменять исходные угловые-маты просто добавленные в следующем помощнике:

 angular.module('httpReal', ['ng']) .config(['$provide', function($provide) { $provide.decorator('$httpBackend', function() { return angular.injector(['ng']).get('$httpBackend'); }); }]) .service('httpReal', ['$rootScope', function($rootScope) { this.submit = function() { $rootScope.$digest(); }; }]); 

Он исправляет две проблемы, которые препятствуют прохождению HTTP-запроса:

  1. Восстанавливает оригинальный $httpBackend ;

  2. Предоставляет метод для выполнения запросов, поскольку в противном случае они будут находиться в очереди AngularJS, ожидая цикла дайджеста.

 describe('my service', function() { var myService, httpReal; beforeEach(module('myModule', 'httpReal')); beforeEach(inject(function( _myService_, _httpReal_ ) { myService = _myService_; httpReal = _httpReal_; })); it('should return valid data', function(done) { myService.remoteCall().then( function(data) { expect(data).toBeDefined(); done(); }, function(error) { expect(false).toBeTruthy(); done(); }); httpReal.submit(); }); }); 

Чтобы протестировать мое приложение с помощью реальных бэкэндов, я использовал модифицированную версию angular-mocks

Он работает так же, как и для юнит-тестов в Жасмине.

Я использую его с Jasmine 2.0, поэтому тест выглядит следующим образом:

 it(' myTest', function (done) { _myService.apiCall() .then(function () { expect(true).toBeTruthy(); done() }); }); 

NB: done необходимо из-за асинхронного вызова.

Вот решение, которое я использую для создания настоящих HTTP-вызовов, когда я использую ngMock для модульных тестов. Я в основном использую его для отладки, тестирования API, получения примеров JSON и т. Д.

Я написал более подробное сообщение о решении в своем блоге: « Как тестировать блок с помощью реальных HTTP-вызовов, используя ngMockE2E & passThrough .

Решение состоит в следующем:

 angular.mock.http = {}; angular.mock.http.init = function() { angular.module('ngMock', ['ng', 'ngMockE2E']).provider({ $exceptionHandler: angular.mock.$ExceptionHandlerProvider, $log: angular.mock.$LogProvider, $interval: angular.mock.$IntervalProvider, $rootElement: angular.mock.$RootElementProvider }).config(['$provide', function($provide) { $provide.decorator('$timeout', angular.mock.$TimeoutDecorator); $provide.decorator('$$rAF', angular.mock.$RAFDecorator); $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator); $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator); $provide.decorator('$controller', angular.mock.$ControllerDecorator); }]); }; angular.mock.http.reset = function() { angular.module('ngMock', ['ng']).provider({ $browser: angular.mock.$BrowserProvider, $exceptionHandler: angular.mock.$ExceptionHandlerProvider, $log: angular.mock.$LogProvider, $interval: angular.mock.$IntervalProvider, $httpBackend: angular.mock.$HttpBackendProvider, $rootElement: angular.mock.$RootElementProvider }).config(['$provide', function($provide) { $provide.decorator('$timeout', angular.mock.$TimeoutDecorator); $provide.decorator('$$rAF', angular.mock.$RAFDecorator); $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator); $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator); $provide.decorator('$controller', angular.mock.$ControllerDecorator); }]); }; 

Включите этот исходный файл после ngMock, например:

     

Как написать тест?

  describe('http tests', function () { beforeEach(module('moviesApp')); var $controller; var $httpBackend; var $scope; describe('real http tests', function() { beforeEach(angular.mock.http.init); afterEach(angular.mock.http.reset); beforeEach(inject(function(_$controller_, _$httpBackend_) { $controller = _$controller_; $scope = {}; $httpBackend = _$httpBackend_; // Note that this HTTP backend is ngMockE2E's, and will make a real HTTP request $httpBackend.whenGET('http://www.omdbapi.com/?s=terminator').passThrough(); })); it('should load default movies (with real http request)', function (done) { var moviesController = $controller('MovieController', { $scope: $scope }); setTimeout(function() { expect($scope.movies).not.toEqual([]); done(); }, 1000); }); }); }); 

Как это работает?

Он использует версию ngMockE2E $ httpBackEndProvider, которая предоставляет нам функцию passThrough, которая, как мы видим, используется в тесте. Это делает, как следует из названия, и пропускает собственный HTTP-вызов.

Нам нужно переопределить модуль ngMock без его фальшивой версии $ BrowserProvider, так как это предотвращает реальные HTTP-вызовы в модульных тестах, которые используют ngMock.

Почему я так делаю?

Мне нравится гибкость, позволяющая легко переключаться между использованием подделок и настоящими HTTP-вызовами, поскольку это помогает моему документообороту при написании тестов, поэтому используется версия ngMockE2E $ httpBackEndProvider. Это также позволяет мне кодировать модульные тесты так же, как с помощью ngMock, где я могу просто вставить / исключить строку beforeEach / afterEach, чтобы зарегистрировать angular.mock.http.init / reset.

Plunkr

Вот пример Plunkr с примером .

  • Эквивалент $ compile в Angular 2
  • Каким образом можно использовать угловые2 HTTP-запросы с защитой Django CSRF?
  • Как импортировать угловой материал в проект?
  • Угловой 2 выход с выхода маршрутизатора
  • Как реализовать Modal Dialog в Angular 2 и выше
  • Угловой 2.0 и модальный диалог
  • localStorage не определен (Angular Universal)
  • Как загрузить файл с помощью Angular2
  • Угловой 2 http не получается
  • Как правильно установить заголовок запроса Http в Angular 2
  • Импорт lodash в приложение углового2 +
  • Interesting Posts

    Каков наилучший способ сделать обратный цикл в C / C # / C ++?

    Непонимание понимания групп и обратных ссылок

    Руководство по convert_imageset.cpp

    Как раздел может быть заполнен, если du ​​не показывает его?

    Сколько символов можно сопоставить с Unicode?

    Нужны ли новые батарейки для ноутбука, прежде чем заряжать их?

    Как проверить, являются ли два выражения <Func > одинаковыми

    Весь VPN-трафик проходит через VPN-сервер или это только для проверки подлинности?

    Как я могу автоматизировать диалоговое окно «Сохранить как» в IE11 с помощью VBA?

    Попытка прозрачным методом безопасности ‘WebMatrix.WebData.PreApplicationStartCode.Start ()’

    Почему мой домашний компьютер обновляет обои для рабочего стола

    Атака VNC на OS X 10.10 – нужно ли мне беспокоиться / отвечать?

    Установить пользователя системы системы suoop для клиента, встроенного в Java webapp

    Как проверить правильность URL-адреса в Android

    Android O – Старая служба переднего плана начала работать?

    Давайте будем гением компьютера.