Reputation: 71
I'm trying to write jasmine tests for http.get() requests that are made as part of the instantiation of my controller:
e.g
angular.module('dashboard').controller('DashboardCtrl', ['$scope', '$rootScope', '$http', function($scope, $rootScope, $http) {
$scope.module_names = [
[0, 'WorkforceMap', null, null],
[10, 'Engagement SentiMap', 'Sentiment', 'engagement'],
[11, 'Change SentiMap', 'Sentiment', 'change'],
];
$http.get('api/info', {cache: true}).success(function(data) {
$rootScope.dash_info = data;
var comp = $rootScope.components = [];
for(var i = 0; i < scope.module_names.length; i++) {
var mod = scope.module_names[i];
if(mod[0] in data.modules)
comp.push([mod[1], mod[3]]);
else
del_module(mod[2], mod[3]);
}
});
$http.get('api/population_data', {cache: true}).success(function(data) {
$rootScope.population_data = data;
});
And a few more http requests as well.
I'm trying to write unit tests using httpBackend for the first api call 'api/info', and have been struggling.
describe("DashboardCtrl Tests", function(){
beforeEach(module('dashboard'));
var scope;
var $httpBackend;
var controller;
beforeEach(inject(function(_$controller_, _$httpBackend_, $rootScope, $injector){
scope = $rootScope.$new();
controller = _$controller_('DashboardCtrl', {$scope: scope});
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('/api/info').respond({'short': 'hi'});
}));
describe('$http.get(api/info)', function(){
it(' receives data from dashboard/:profile_id/api/info', function(){
$httpBackend.expectGET('api/info');
$httpBackend.flush();
});
});
});
I think the reason i've been struggling is that i haven't been able to find out how to single out one http.get request, since all requests are executed when the controller is instantiated.
My most recent error is "ReferenceError: Can't find variable: scope"
I'll keep digging around, but if anyone has seen something like this before, I would greatly appreciate some guidance!
Thanks
Upvotes: 2
Views: 2370
Reputation: 3543
What I do in that case is isolate call in methods, you can at minimum wrap all of this in a $scope.init function and test it.
A nicer way would be to cut that on smaller function, and the best way, to have a service wich return $http promise in those smaller function.
An exemple of init :
angular.module('dashboard').controller('DashboardCtrl', ['$scope', '$rootScope', '$http', function($scope, $rootScope, $http) {
$scope.init = function (){
$scope.module_names = [
[0, 'WorkforceMap', null, null],
[10, 'Engagement SentiMap', 'Sentiment', 'engagement'],
[11, 'Change SentiMap', 'Sentiment', 'change'],
];
$scope.info();
$http.get('api/population_data', {cache: true}).success(function(data) {
$rootScope.population_data = data;
});
};
$scope.info = function (){
$http.get('api/info', {cache: true}).success(function(data) {
$rootScope.dash_info = data;
var comp = $rootScope.components = [];
for(var i = 0; i < scope.module_names.length; i++) {
var mod = scope.module_names[i];
if(mod[0] in data.modules)
comp.push([mod[1], mod[3]]);
else
del_module(mod[2], mod[3]);
}
});
};
$scope.init();
And in test :
describe('$http.get(api/info)', function(){
it(' receives data from dashboard/:profile_id/api/info', function(){
$httpBackend.expectGET('api/info').respond({'title':'test'});
scope.info();
$httpBackend.flush();
$rootScope.$digest();
expect($rootScope.dash_info).toEqual({'title':'test'});
});
});
Upvotes: 0