Как мне имитировать или заглушать вызов AJAX, который выполняется при загрузке?

#angularjs #jasmine #karma-jasmine

#angularjs #jasmine #карма-жасмин

Вопрос:

У меня есть приложение angular, которое вызывает 2 службы перед загрузкой, и я хотел бы имитировать или заглушать эти вызовы. В противном случае karma пытается выполнить эти вызовы и продолжает показывать ошибки в консоли.

Как бы я это сделал?

Смотрите Функции getConfig() и getUser() ниже:

JavaScript:

 import appConstant from './app-gouvernementales.constant.js';
import appConfig from './app-gouvernementales.config.js';
import appRun from './app-gouvernementales.run.js';
import AppComponent from './app-gouvernementales.component.js';

const requires = [
  'ngMessages',
  'ngRoute',
  'ngSanitize',
  'permission',
  'permission.ng',
  'ngMockE2E',
];

const app = angular
  .module('app-gouvernementales', requires)
  .config(appConfig)
  .run(appRun)
  .component('appGouvernementales', AppComponent)
  .name;

// create and bootstrap application
getConfig()
  .then((config) => {
    angular.module('app-gouvernementales')
      .constant('APP_SETTINGS', appConstant(config));

    return { url: `${config.protocol}://${config.host}`, uid: config.shibbolethUid };
  })
  .then(data => getUser(data.url, data.uid))
  .catch((err) => {
    console.log(err);
    document.location.href = '/erreur/role';
  })
  .then((_user_) => {
    const user = _user_.data;

    angular.module('app-gouvernementales')
      .constant('USER', user);
  })
  .then(() => {
    angular.bootstrap(document, ['app-gouvernementales']);
  });

function getConfig() {
  const initInjector = angular.injector(['ng']);
  const $http = initInjector.get('$http');

  return $http.get('/gouvernementales/app-gouvernementales.config.json')
    .then(response => response.data);
}

function getUser(url, uid) {
  const initInjector = angular.injector(['ng']);
  const $http = initInjector.get('$http');

  return $http.get(`${url}/roles`, { withCredentials: true, headers: { 'X-uid': uid } });
}

export default app;
  

Ответ №1:

Вероятно, вы могли бы сделать это с $httpBackend помощью .

 var $httpBackend;
var yourMockedObject = {};

beforeEach(angular.mock.inject(function (_$httpBackend_) {
    $httpBackend = _$httpBackend_
    $httpBackend.expect('GET', 'the/url').respond(yourMockedObject);
}));

afterEach(function () {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
});
  

Но в идеале вы не хотите загружать все приложение при модульном тестировании, а только конкретный модуль, который вы хотите протестировать. В этом случае вы можете имитировать данные, переданные этому модулю.

Комментарии:

1. Означает ли это, что когда я выбираю, какой файл karma должен загружаться, это не должен быть «файл точки входа», который импортирует все?

2. Хорошо, итак, я отделил создание модуля корневого приложения от файла начальной загрузки и настроил Karma на загрузку только файла модуля приложения и всех спецификаций. Большинство моих тестов работают, но по какой-то причине какой-то случайный компонент или служба просто не загружаются … и я просто не могу понять, почему…

3. Это почти похоже на то, что предыдущий тест влияет на следующие

4. Вы должны загрузить все файлы в свой karma conf. Но в ваших тестах создается только экземпляр соответствующего модуля angular.mock.module('somePartOfTheAppModule');

5. Итак, после большого тестирования некоторые модули будут загружаться, некоторые не будут, некоторые компоненты или службы будут загружаться, другие не будут… После проверки с 3 разработчиками это становится все более и более странным, и не похоже, что это решение. Я не могу поверить, что тесты так сложно настроить в 2016 году.