$ httpBackend.flush () still requires a timeout to identify objects

I am keen on my karma AngularJS application and ending with a backend with $ HttpBackend. Somehow, the flush () method does not seem to allow all my requests, as some of the variables in the controller remain undefined. However, if I add a timeout before resolving my expectation, it works great!

My controller:

feedbackApp.controller('CompetenceCtrl', [ '$scope', '$location', 'Restangular', function CompetenceCtrl($scope, $location, Restangular) { $scope.compId = null; $scope.index = null; Restangular.one('questionnaires',1).get().then(function (q) { $scope.questionnaire = q; angular.forEach($scope.questionnaire.competences, function (value, key) { var compTemp = new models.Competence(value); if (!compTemp.finished() && $scope.compId === null) { $scope.compId = compTemp.id; $scope.index = key; } }); getCompetence($scope.compId); }); function getCompetence(compId) { Restangular.one('questionnaires',1).one('competences', compId).get().then(function (c) { $scope.competence = c; }); } }]); 

My specifications:

 'use strict'; describe('Controller: CompetenceCtrl', function () { //load the controller module beforeEach(module('360FeedbackApp', 'mockQuestionnaire', 'mockCompetences')); var $httpBackend, $scope, $location, createController; beforeEach(inject(function ($injector, _Restangular_,defaultQuestionnaire, defaultCompetences) { // Set up the mock http service responses $httpBackend = $injector.get('$httpBackend'); // backend definition common for all tests $httpBackend.whenGET(apiUrl + '/questionnaires/1').respond(defaultQuestionnaire); $httpBackend.whenGET(apiUrl + '/questionnaires/1/competences/1').respond(defaultCompetences.competences[0]); $httpBackend.whenGET(apiUrl + '/questionnaires/1/competences/2').respond(defaultCompetences.competences[1]); $httpBackend.whenGET(apiUrl + '/questionnaires/1/competences/3').respond(defaultCompetences.competences[2]); $httpBackend.whenGET(apiUrl + '/questionnaires/1/competences/4').respond(defaultCompetences.competences[3]); $httpBackend.whenGET(apiUrl + '/questionnaires/1/competences/5').respond(defaultCompetences.competences[4]); $httpBackend.whenPUT(apiUrl + '/questionnaires/1/competences/1').respond(200); $httpBackend.whenPUT(apiUrl + '/questionnaires/1/competences/2').respond(200); $httpBackend.whenPUT(apiUrl + '/questionnaires/1/competences/3').respond(200); $httpBackend.whenPUT(apiUrl + '/questionnaires/1/competences/4').respond(200); $httpBackend.whenPUT(apiUrl + '/questionnaires/1/competences/5').respond(200); // Get hold of a scope (ie the root scope) $scope = $injector.get('$rootScope'); // and the location $location = $injector.get('$location'); // The $controller service is used to create instances of controllers var $controller = $injector.get('$controller'); createController = function () { return $controller('CompetenceCtrl', {'$scope': $scope, '$location': $location, 'Restangular': _Restangular_ }); }; })); afterEach(function () { $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); it('should set the first competence', function () { $httpBackend.expectGET(apiUrl + '/questionnaires/1/competences/1'); createController(); $httpBackend.flush(); //DO NOT UNDERSTAND WHY I NEED THIS TIMEOUT! //THE TEST FAILS WITH 'undefined' IF I DONT USE IT! setTimeout(function() { expect($scope.competence).toBeDefined(); }, 5000); }); 

Any help is much appreciated!

+4
source share
1 answer

If you have promises that need to be addressed (indicated by .then () for your relay call), you should call $ scope. $ digest () after your $ httpBackend.flush () to solve them. It also looks like it might be that your Restangular call gets to the actual server instead of the layout, which will cause you to need a timeout.

+1
source

All Articles