2013-09-26 6 views
4

Я увлекаюсь своим приложением AngularJS с кармой и завершает работу с файлом HttpBackend. Так или иначе, метод flush(), похоже, не разрешает все мои запросы, поскольку некоторые из переменных в контроллере по-прежнему остаются неопределенными. Однако, если я добавлю тайм-аут, прежде чем разрешать свое ожидание, он отлично работает!

Мой контроллер:

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; 
      }); 
     } 
    }]); 

Мои данные:

'use strict'; 

describe('Controller: CompetenceCtrl', function() { 
    //load the controller's 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 (i.e. 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); 
    }); 

Любая помощь очень ценится!

+1

Hm. Попробуйте вызвать '$ scope. $ Apply', а затем проверить значение $ scope.competence. Проблема может заключаться в $ q обещаниях (они не разрешены, если вы не назовете '$ scope. $ Apply') – jusio

+0

Thx. $ scope. $ apply() не сработал, но $ scope.digest() сделал. –

+0

Кроме того, конкретный сценарий выше с таймаутом прошел тест, потому что тайм-аут, ожидаемый() только для пожара ПОСЛЕ всех unittest, уже выполнен. Так что неудача в ожидании не подвела никакого теста ....: S –

ответ

1

Если у вас есть обещания, которые необходимо решить (обозначенные .then() для вашего ретрансляционного вызова), вам нужно вызвать $ scope. $ Digest() после вашего $ httpBackend.flush() для их устранения. Это также похоже на то, что, возможно, ваш ретрансляционный вызов поражает фактический сервер, а не макет, что будет причиной того, что вам понадобится тайм-аут.

+0

На самом деле мне пришлось поставить $ scope. $ Digest() перед $ httpBackend.flush() ..... не совсем точно почему. –

+0

Все зависит от того, что у вас есть вещи в вашем реальном коде. Если таймаут должен быть разрешен до того, как будет выполнено обещание в $ http, это потребует, чтобы заказ был переключен в тестах из того, что я опубликовал. – MBielski