我使用$ 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
答案 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'