$ urlRouterProvider创建$ httpBackend错误

时间:2014-08-23 18:28:35

标签: javascript angularjs karma-runner httpbackend

我使用$ httpBackend服务模拟我的服务测试请求。但是,我开始在我的测试中遇到错误,这些错误表明这些请求实际上是被嘲笑的。当我注释掉我在app app中提供的所有路径时,所有测试都通过了。任何人都可以解释为什么会这样吗?以下是我的代码和错误。

修改 编辑包含Whisher的片段,但不确定我是否正确使用它。

describe('AssetManager', function() {

var state, $httpBackend, AssetManager;

// If the app isn't broken into smaller modules,
// we must load the entire app for each test
beforeEach(function() {
  module('us.assetManager');
  module('statemock');

  inject(function($state, _$httpBackend_, _AssetManager_) {
    state = $state;
    $httpBackend = _$httpBackend_;
    AssetManager = _AssetManager_;
  });

});

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

describe('#getSpendAccounts', function() {

  beforeEach(function() {
    $httpBackend.expectGET('http://localhost:3000/api/facebook/spend_accounts.json').respond([
      {email: 'me@unifiedsocial.com'}
    ]);
  });

  it('fetches the users Spend Accounts', function() {
    var result;

    state.expectTransitionTo('fbCustomAudiences');

    AssetManager.getSpendAccounts('facebook').then(function(data) {
      result = data;
    });

    $httpBackend.flush();

    expect(result.data[0].email).toBe('me@unifiedsocial.com');
  });

});

app.js

(function() {
  'use strict';

   angular
     .module('us.assetManager', ['ui.router'])
     .config(function ($stateProvider, $urlRouterProvider) {
       // catch all route
      $urlRouterProvider.otherwise('/facebook/custom_audiences');

  $stateProvider
    .state('fbCustomAudiences', {
      abstract: true,
      templateUrl: '/common/views/layout.html',
      controller: 'CustomAudiencesCtrl as audiences',
      data: {
        network: 'facebook'
      },
      resolve: {
        getSpendAccounts: function(AssetManager) {
          return AssetManager.getSpendAccounts('facebook');
        }
      }
    })
    .state('fbCustomAudiences.root', {
      url: '/facebook/custom_audiences',
      views: {
        'breadcrumbs': {
          templateUrl: 'facebook/views/breadcrumbs.html'
        },
        'sidebar': {
          templateUrl: 'facebook/views/sidebar.html'
        },
        'acctControls': {
          templateUrl: 'facebook/views/controls.html'
        },
        'table': {
          templateUrl: 'facebook/views/custom-audiences-table.html'
        }
      }
    })
    .state('fbCustomAudiences.spendAccount', {
      url: '/facebook/custom_audiences/:spendAccountId',
      views: {
        'breadcrumbs': {
          templateUrl: 'facebook/views/breadcrumbs.html'
        },
        'sidebar': {
          templateUrl: 'facebook/views/sidebar.html'
        },
        'acctControls': {
          templateUrl: 'facebook/views/controls.html'
        },
        'table': {
          templateUrl: 'facebook/views/custom-audiences-table.html'
        }
      },
      resolve: {
        getAdAccounts: function(getSpendAccounts, AssetManager, $stateParams) {
          var spendAccountId = parseInt($stateParams.spendAccountId);

          // set the selectedSpendAccount for the dropdown
          AssetManager.selectedSpendAccount = _.find(getSpendAccounts.data, function(spendAccount) {
            return spendAccount.id === spendAccountId;
          });

          return AssetManager.getAdAccounts('facebook', spendAccountId);
        }
      }
    })
    .state('fbCustomAudiences.spendAccount.adAccount', {
      url: '/:adAccountId',
      views: {
        'breadcrumbs': {
          templateUrl: 'facebook/views/breadcrumbs.html'
        },
        'sidebar': {
          templateUrl: 'facebook/views/sidebar.html'
        },
        'acctControls': {
          templateUrl: 'facebook/views/controls.html'
        },
        'table': {
          templateUrl: 'facebook/views/custom-audiences-table.html'
        }
      },
      resolve: {
        getCustomAudiences: function(getAdAccounts, AssetManager, $stateParams) {
          var adAccountId = parseInt($stateParams.adAccountId);

          // set the selectedAdAccount for the dropdown
          AssetManager.selectedAdAccount = _.find(getAdAccounts.data, function(adAccount) {
            return adAccount.id === adAccountId;
          });

          return AssetManager.getAudiencesSummaryData('facebook', adAccountId);
        }
      }
    })
  });
})();

AssetManager.js

(function() {
'use strict';

angular
  .module('us.assetManager')
  .factory('AssetManager', AssetManager);


AssetManager.$inject = ['$http', '$state'];

function AssetManager($http, $state) {

// domain for HTTP endpoints
// StackOverflow doesnt allow localhost so just wrote domain
var domain = 'http://domain:3000/api/';

var spendAccounts = [],
    adAccounts = [],
    audiencesSummaryData = [],
    selectedSpendAccount = {},
    selectedAdAccount = {},
    selectedAudience = {},
    placeholder = null;

var factory = {
  spendAccounts: spendAccounts,
  adAccounts: adAccounts,
  selectedSpendAccount: selectedSpendAccount,
  audiencesSummaryData: audiencesSummaryData,
  selectedAdAccount: selectedAdAccount,
  selectedAudience: selectedAudience,
  placeholder: placeholder,
  getSpendAccounts: getSpendAccounts,
  getAdAccounts: getAdAccounts,
  getAudiencesSummaryData: getAudiencesSummaryData,
  getAudience: getAudience,
  createAudience: createAudience,
  editAudience: editAudience,
  deleteAudience: deleteAudience,
  setSelectedSpendAccount: setSelectedSpendAccount,
  setSelectedAdAccount: setSelectedAdAccount,
  hasSelectedSpendAccount: hasSelectedSpendAccount,
  hasSelectedAdAccount: hasSelectedAdAccount,
  hasSelectedAccounts: hasSelectedAccounts,
  setPlaceholder: setPlaceHolder
};

return factory;

// all URLs will change domains

function getSpendAccounts(socialNetwork) {
  var url = domain + socialNetwork + '/spend_accounts.json',
      AssetManager = this;

  return $http.get(url)
    .success(function(data) {
      AssetManager.spendAccounts = data;
    })
    .error(function() {
      console.log('Could not retrieve Spend Accounts.');
    });
}

function getAdAccounts(socialNetwork, spendAccountId) {
  var url = domain + socialNetwork + '/ad_accounts/' + spendAccountId + '.json'
      AssetManager = this;

  return $http.get(url)
    .success(function(data) {
      AssetManager.adAccounts = data;
    })
    .error(function() {
      console.log('Could not retrieve Ad Accounts.');
    });
}

function getAudiencesSummaryData(socialNetwork, adAccountId) {
  var url = domain + socialNetwork + '/audiences_summary_data/' + adAccountId + '.json',
      AssetManager = this;

  return $http.get(url)
    .success(function(data) {
      AssetManager.audiencesSummaryData = data;
    })
    .error(function() {
      console.log('Could not retrieve Audiences summary data.');
    });
}

function getAudience(socialNetwork, adAccountId, audienceId) {
  var url = domain + socialNetwork + '/audience/' + adAccountId + '/' + audienceId + '.json',
      AssetManager = this;

  return $http.get(url)
    .success(function(data) {
      AssetManager.selectedAudience = data;
    })
    .error(function() {
      console.log('Could not retrieve Audience with id: ' + audienceId);
    });
}

AssetManager.spec.js

(function() {
'use strict';

describe('AssetManager', function() {

var AssetManager, $httpBackend;

// If the app isn't broken into smaller modules,
// we must load the entire app for each test
beforeEach(function() {
  module('us.assetManager');

  inject(function(_$httpBackend_, _AssetManager_) {
    $httpBackend = _$httpBackend_;
    AssetManager = _AssetManager_
  });

});

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

describe('#getSpendAccounts', function() {

  beforeEach(function() {
    $httpBackend.expectGET('http://localhost:3000/api/facebook/spend_accounts.json');
    $httpBackend.whenGET('http://localhost:3000/api/facebook/spend_accounts.json').respond([
      {email: 'me@unifiedsocial.com'}
    ]);
  });

  it('fetches the users Spend Accounts', function() {
    var result;

    AssetManager.getSpendAccounts('facebook').then(function(data) {
      result = data;
    });

    $httpBackend.flush();

    expect(result.data[0].email).toBe('me@unifiedsocial.com');
  });

});

describe('#getAdAccounts', function() {

  beforeEach(function() {
    $httpBackend.expectGET('http://localhost:3000/api/facebook/ad_accounts/1.json').respond([
      {
        "id": 1,
        "spend_account_id": 1,
        "name": "Unified",
        "initiatives": 3,
        "audiences": 5,
        "pixels": 5,
        "spend": 25000
      }
    ]);
  });

  it('fetches the Spend Accounts Ad Accounts', function() {
    var result;

    AssetManager.getAdAccounts('facebook', '1').then(function(data) {
      result = data;
    });

    $httpBackend.flush();

    expect(result.data[0].name).toBe('Unified');
  });

});

describe('#getAudiencesSummaryData', function() {

  beforeEach(function() {
    $httpBackend.expectGET('http://localhost:3000/api/facebook/audiences_summary_data/1.json').respond([
      {
        'id': 'facebook_id1',
        'name': 'A Name of audience',
        'source': {
          'type': 'Website',
          'detail': 'Custom Audience'
        },
        'count': 2500,
        'timeCreated': new Date('Fri Aug 08 2014 10:29:43 GMT-0400 (EDT)'),
        'status': {
          'deliveryStatus': 'NOT READY',
          'deliveryDescription': 'Audience is < 20 people',
          'operationStatus': 'Operation status??',
          'operationDescription': 'Operation description??'
        }
      },
      {
        'id': 'facebook_id2',
        'name': 'B Name of audience',
        'source': {
          'type': 'Lookalike',
          'detail': 'Custom Audience'
        },
        'count': 2700,
        'timeCreated': new Date('Fri Aug 05 2014 10:29:43 GMT-0400 (EDT)'),
        'status': {
          'deliveryStatus': 'READY',
          'deliveryDescription': 'Audience is < 20 people',
          'operationStatus': 'Operation status??',
          'operationDescription': 'Operation description??'
        }
      }
    ]);
  });

  it('fetches the custom audience summary data', function() {
    var result;

    AssetManager.getAudiencesSummaryData('facebook', '1').then(function(data) {
      result = data;
    });

    $httpBackend.flush();

    expect(result.data[0].name).toBe('A Name of audience');
  });

});

所有请求的错误都是相同的

PhantomJS 1.9.7 (Mac OS X) AssetManager #getSpendAccounts fetches the users Spend Accounts FAILED
Error: Unexpected request: GET http://localhost:3000/api/facebook/spend_accounts.json
No more request expected
    at $httpBackend (/Users/evankline/unified/asset-manager/bower_components/angular-mocks/angular-mocks.js:1179)
    at sendReq (/Users/evankline/unified/asset-manager/bower_components/angular/angular.js:8334)
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:8066
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:11546
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:11546
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:11632
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:12658
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:12470
    at /Users/evankline/unified/asset-manager/bower_components/angular-mocks/angular-mocks.js:1438
    at /Users/evankline/unified/asset-manager/test/spec/common/services/AssetManager.spec.js:47
Error: Unexpected request: GET /common/views/layout.html
No more request expected
    at $httpBackend (/Users/evankline/unified/asset-manager/bower_components/angular-mocks/angular-mocks.js:1179)
    at sendReq (/Users/evankline/unified/asset-manager/bower_components/angular/angular.js:8334)
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:8066
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:11546
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:11546
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:11632
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:12658
    at /Users/evankline/unified/asset-manager/bower_components/angular/angular.js:12470
    at /Users/evankline/unified/asset-manager/bower_components/angular-mocks/angular-mocks.js:1470
    at /Users/evankline/unified/asset-manager/test/spec/common/services/AssetManager.spec.js:28

1 个答案:

答案 0 :(得分:0)

您的代码和测试中的网址不同。在测试中你嘲笑了

的请求
'http://localhost:3000/api/facebook/spend_accounts.json'

但根据你的代码

var domain = 'http://domain:3000/api/';    
...
function getSpendAccounts(socialNetwork) {
      var url = domain + socialNetwork + '/spend_accounts.json',
          AssetManager = this;
    //do request..
    }

url应该是

'http://domain:3000/api/facebook/spend_accounts.json'