Подтвердить что ты не робот

AngularJS + Жасмин: $httpBackend работает не так, как ожидалось

Я использую Жасмин с Кармой для тестирования моего приложения, построенного на Angular.

Я должен протестировать службу, которая загружает пользовательские данные, и я использую $httpBackend для издевательства над ответами. Однако, когда я запускаю тест, у меня есть две ошибки:

  • Ошибка: нет ожидающего запроса на флеш!
  • Ошибка: неудовлетворенные запросы: GET https://api.github.com/users/wilk

Модуль:

'use strict';

app.service ('UserService', ['$resource', '$q', 'GITHUB_API_URL', function ($resource, $q, GITHUB_API_URL) {
  var userResource = $resource (GITHUB_API_URL + '/users/:user', {user: '@user'}) ,
      userModel = {};

  return {
    data: function () {
        return userModel;
    } ,
    populate: function (user) {
      var deferred = $q.defer () ,
          userRequest = userResource.get ({user: user});

      $q
          .when (userRequest.$promise)
          .then (function (data) {
              userModel = data;
              deferred.resolve (data);
          });

      return deferred.promise;
    }
  };
}]);

Тест:

'use strict';

describe ('Service: UserService', function () {
    beforeEach (module ('myApp'));

    var $appInjector = angular.injector (['myApp']) ,
        UserService = $appInjector.get ('UserService') ,
        GITHUB_API_URL = $appInjector.get ('GITHUB_API_URL') ,
        GITHUB_USER = $appInjector.get ('GITHUB_USER') ,
        $httpBackend;

    beforeEach (inject (function ($injector) {
        $httpBackend = $injector.get ('$httpBackend');

        $httpBackend
            .when ('GET', GITHUB_API_URL + '/users/' + GITHUB_USER)
            .respond ({
                login: GITHUB_USER ,
                id: 618009
            });
    }));

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

    describe ('when populate method is called', function () {
        it ('should returns user data', function () {
            $httpBackend.expectGET (GITHUB_API_URL + '/users/' + GITHUB_USER);

            UserService.populate (GITHUB_USER);
            $httpBackend.flush ();
            expect(UserService.data ()).toEqual ({
                login: GITHUB_USER ,
                id: 618009
            });

        });
    });
});

Предположим, что GITHUB_API_URL равен 'https://api.github.com/', а GITHUB_USER равен 'wilk'.

Я запускаю этот тест с Карма-Жасмин 0.1.5 и AngularJS 1.2.6 (с Angular Mocks и сценарием 1.2.6).

Что не так с этим кодом?

4b9b3361

Ответ 1

Расскажите о каждой ошибке отдельно:

Ошибка: нет ожидающего запроса на сброс!

Это происходит потому, что через $httpBackend не было сделано никаких запросов, поэтому ничего не нужно скрывать. Это потому, что вы создаете UserService до $httpBackend, и поэтому Angular не знает, что он должен использовать его вместо реального $http. Если вы проверите консоль, вы увидите, что отправляется реальный запрос.

Ошибка: неудовлетворенные запросы: GET https://api.github.com/users/wilk

По той же причине, что и выше. Поскольку $httpBackend не используется службой, ожидание, которое вы создали, никогда не выполняется.

Здесь ваш spec refactored после рассмотрения всего вышеперечисленного:

describe ('Service: UserService', function () {
    var UserService,
        GITHUB_API_URL,
        GITHUB_USER,
        $httpBackend;

    beforeEach(function() {
      module('plunker');

      inject(function( _$httpBackend_, _UserService_, _GITHUB_API_URL_, _GITHUB_USER_) {
        $httpBackend = _$httpBackend_;
        UserService = _UserService_;
        GITHUB_API_URL = _GITHUB_API_URL_;
        GITHUB_USER = _GITHUB_USER_;
      });
    });

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

    describe ('when populate method is called', function () {
        it ('should returns user data', function () {
            $httpBackend
              .whenGET(GITHUB_API_URL + '/users/' + GITHUB_USER)
              .respond ({
                  login: GITHUB_USER,
                  id: 618009
              }); 

            UserService.populate(GITHUB_USER);
            $httpBackend.flush();

            expect(UserService.data().login).toBe(GITHUB_USER);
            expect(UserService.data().id).toBe(618009);
        });
    });
});

Plunker

Примечание. Я изменил способ ввода данных немного, но то, что вы делаете, просто отлично, если вы создаете $httpBackend перед всем остальным.