1

我有一个触发 HTTP 请求的服务。此请求使用 $rootScope.config 对象(存储了我的基本 url),但由于某种原因,当我使用 $httpBackend 时,$rootScope 未正确加载。

服务:

myAppServices.factory('Auth', function($rootScope, $http, $cookieStore){   
  return {
    logout: function(success, error) {
      $http.get($rootScope.config.apiUrl + '/users/logout').then(function(response){
      }, function(response) {
      });
    }

测试:

describe('services', function() {
  var Auth;
  var $httpBackend;
  var $cookieStore;
  var $rootScope;

  beforeEach(function() {
    module('myApp.services');
  });

  beforeEach(inject(function($injector) {
    $httpBackend = $injector.get('$httpBackend');
    $cookieStore = $injector.get('$cookieStore');
    $rootScope = $injector.get('$rootScope');
    Helper = $injector.get('Helper');
    Auth = $injector.get('Auth');
  }));

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

describe('logout', function() {
  it('should make a request and invoke callback', function() {
    // I try to set $rootScope here, works in my other tests, but not in this test
    $rootScope = { config: { apiUrl: 'foo' } };

    var invoked = false;
    var success = function() {
      invoked = true;
    };
    var error = function() {};

    $httpBackend.expectPOST('/logout').respond();
    Auth.logout(success, error);
    $httpBackend.flush();
    $rootScope = { config: { apiUrl: 'foo' } };
    expect(invoked).toEqual(true);

当我在测试中将 $rootScope 设置为某个值时,它通常可以工作,但在这个测试中却不行。

使用 $httpBackend 时,为什么 $rootScope 在我的服务中没有配置属性?

4

1 回答 1

5

问题:

有两种不同的同名事物会引起混淆:

  • $rootScope(实际$rootScope是所有 Scopes 的祖先,通过 Angular 的依赖注入注入)。
  • 并且有一个名为$rootScope您在测试套件中声明的局部变量。

为了清楚起见,我将后者称为$rootScope{var}.


这是发生了什么:

  1. 在某些时候$rootScope将被注入到您的服务的构造函数中(稍后在发出$http请求时使用)。

  2. $rootScope{var}被初始化为返回的值$injector.get('$rootScope');
    此时$rootScope$rootScope{var}都是同一个对象。

  3. 此行:$rootScope = { config: { apiUrl: 'foo' } };创建一个对象并将其分配为 的值$rootScope{var}
    此时$rootScope不再$rootScope{var}是同一个对象了。

  4. $rootScope{var}确实有一个config属性,但是您的服务将使用$rootScope,它对 . 一无所知config


解决方案:

为了将config属性添加到实际$rootScope更改中,您的代码如下所示:

$rootScope.config = { apiUrl: 'foo' };
于 2014-01-14T21:03:37.450 回答