2013-09-26 80 views
4

我用Karma對我的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

嗯。嘗試調用'$ scope。$ apply',然後檢查'$ scope.competence'的值。問題可能出現在$ q promises中(除非調用'$ scope。$ apply',否則它們不會被解析) – jusio

+0

Thx。 $ scope。$ apply()沒有解決,但$ scope.digest()做了。 –

+0

此外,具有超時的上述特定情況已通過測試,因爲超時使expect()僅在所有unittest已被執行後觸發。所以沒有達到期望沒有通過任何測試....:S –

回答

1

如果您有需要解決的承諾(由Restangular調用中的.then()指示),您需要在$ httpBackend.flush()後面調用$ scope。$ digest()來解決它們。這聽起來像也許你的Restangular調用是擊中實際的服務器而不是模擬,這將是什麼導致你需要超時。

+0

實際上我不得不把$ scope。$ digest()放在$ httpBackend.flush().....之前,不完全確定爲什麼。 –

+0

這一切都取決於你在你的實際代碼中的東西的順序。如果超時需要在你的$ http promise之前解決,那就需要在我發佈的測試中切換命令。 – MBielski