首页 文章

AngularJS Jasmine:$ httpBackend没有按预期工作

提问于
浏览
22

我正在使用带有 KarmaJasmine 来测试我在 Angular 上构建的应用程序 .

我've to test a service that loads user data and I'使用$ httpBackend模拟响应 . 但是,当我运行测试时,我遇到了两个错误:

  • Error: No pending request to flush!

  • Error: Unsatisfied requests: GET https://api.github.com/users/wilk

Module:

'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;
    }
  };
}]);

Test:

'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' .

我正在使用 Karma-Jasmine 0.1.5AngularJS 1.2.6 (使用Angular Mocks和Scenario 1.2.6)运行此测试 .

这段代码出了什么问题?

1 回答

  • 48

    我们分别讨论每个错误:

    Error: No pending request to flush!

    这种情况正在发生,因为没有通过 $httpBackend 发出请求,所以有's nothing to flush. That'因为你在 $httpBackend 之前实例化 UserService 所以Angular不知道它应该使用它而不是真正的 $http . 如果您检查控制台,您将看到正在发送真实请求 .

    Error: Unsatisfied requests: GET https://api.github.com/users/wilk

    与上述相同的原因 . 由于 $httpBackend isn 't being used by the service, the expectation you' ve创建永远不会实现 .

    在考虑了以上所有内容之后,这是您的规范重构:

    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 .

相关问题