I'm using the $httpBackend service to mock requests for my Service tests. However, I began getting errors in my tests that suggested the requests were actually being made vs being mocked. When I commented out the catch all route I provided in my app config the tests all passed. Can anyone explain why this is happening? Below is my code and errors.
EDIT Edited to include Whisher's snippet but not sure im using it correctly.
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');
});
});
ERRORS ARE SAME FOR ALL REQUESTS
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