2013-09-26 3 views
4

AngularJS 앱을 카르마와 함께 unittesting하고 백엔드를 $ 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

흠. '$ scope. $ apply'를 호출하고'$ scope.competence' 값을 확인하십시오. 문제는 $ q 약속에있을 수 있습니다 ('$ scope. $ apply'를 호출하지 않으면 해결되지 않습니다) – jusio

+0

Thx. $ scope. $ apply()가 작동하지 않았지만 $ scope.digest()가 작동했습니다. –

+0

또한, timeout이 모든 unittest가 이미 실행 된 후에 만 ​​발생하도록 expect()를 설정했기 때문에 시간 초과가있는 특정 시나리오가 테스트를 통과했습니다. 그래서 기대를 충족시키지 못하면 어떤 테스트도 실패하지 않았다 .... : S –

답변

1

해결해야 할 약속이있는 경우 (Restangular 호출에서 .then()로 표시) $ http. $ digest()를 호출하여 $ httpBackBack.flush()를 호출하여 해결해야합니다. 이것은 또한 귀하의 Restangular 통화가 모의가 아니라 실제 서버를 강타하고있는 것처럼 들리므로 시간 초과가 필요한 원인이 될 수 있습니다.

+0

사실 $ scope.flush() 전에 $ digest() ..... 정확히 이유를 모르겠다. –

+0

모두는 실제 코드에있는 순서에 따라 다릅니다. $ http 약속 전에 타임 아웃을 해결해야한다면, 내가 게시 한 것을 테스트에서 전환하도록 요구할 것입니다. – MBielski