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

Wil*_*ilk 22 service unit-testing jasmine angularjs karma-runner

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

我将测试一个加载用户数据的服务,我使用$ httpBackend来模拟响应.但是,当我运行测试时,我遇到了两个错误:

模块:

'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;
    }
  };
}]);
Run Code Online (Sandbox Code Playgroud)

测试:

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

        });
    });
});
Run Code Online (Sandbox Code Playgroud)

让我们假设GITHUB_API_URL等于" https://api.github.com/ "和GITHUB_USER等于"威尔克".

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

这段代码出了什么问题?

Mic*_*ord 48

我们分别讨论每个错误:

错误:没有待处理的待处理请求!

这是因为没有通过请求$httpBackend,所以没有什么可以刷新.那是因为你UserService之前在实例化$httpBackend,所以Angular不知道它应该使用它而不是真实的$http.如果您检查控制台,您将看到正在发送真实请求.

错误:不满意的请求:获取https://api.github.com/users/wilk

与上述相同的原因.由于$httpBackend服务未使用,因此您创建的期望永远不会实现.

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

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);
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

Plunker

注意:我已经改变了注入事物的方式,但是你做的方式很好,只要你$httpBackend在其他事情之前创建.

  • @Wilk当你调用`module('myApp')`Angular加载模块包含的所有服务时,注入器可以使用它们中的任何一个.param名称中的下划线只是为了防止变量名称发生冲突.Angular只是忽略了它们.但是,如果您的局部变量具有不同的名称,则不需要使用它们.关于[这里]的更多信息(http://docs.angularjs.org/api/angular.mock.inject). (3认同)
  • 哇!+1为伟大的答案!清晰细致!感谢您的解释!但是我还不明白'注入'功能是如何工作的.如何注入这些重命名的参数?我的意思是,它如何知道_UserService_它是我模块的服务? (2认同)