2015-02-09 129 views
2

我試圖寫一個控制器,它會從一個服務承諾的單元測試,但在茉莉花我正在讀測試AngularJS控制器的未定義的屬性「然後」:類型錯誤:無法與噶

TypeError: Cannot read property 'then' of undefined 

在控制器中,我致電.then()返回服務承諾。

任何人都可以幫忙嗎?我肯定錯過了一些明顯的東西。

這裏是一個普拉克:http://plnkr.co/edit/vJOopys7pWTrTQ2vLgXS?p=preview

'use strict'; 

describe('Language controller', function() { 
    var scope, translationService, createController; 

    beforeEach(function() { 
     var mockTranslationService = {}; 
     module('dictApp', function($provide) { 
      $provide.value('translationService', mockTranslationService); 
     }); 

     inject(function($q) { 
      mockTranslationService.languages = [ 
       { 
        name: 'slovak' 
       }, 
       { 
        name: 'czech' 
       } 
      ]; 

      mockTranslationService.languagesWithWords = [{ 
       name: 'slovak', 
       words: [{ 
        key: 'Car', 
        translation: 'Auto', 
        createdOn: 0 
       }, { 
        key: 'Flower', 
        translation: 'Kvet', 
        createdOn: 0 
       }] 
      }, { 
       name: 'czech', 
       words: { 
        key: 'Plaza', 
        translation: 'Namesti', 
        createdOn: 0 
       } 
      }]; 

      mockTranslationService.getLanguages = function() { 
       var deferred = $q.defer(); 

       deferred.resolve(this.languages); 
       return deferred.promise; 
      }; 
     }); 
    }); 

    beforeEach(inject(function($controller, $rootScope, _translationService_) { 
     scope = $rootScope.$new(); 
     translationService = _translationService_; 
     createController = function() { 
      return $controller('LanguageCtrl', 
        {$scope: scope, translationService: translationService}); 
     }; 
     scope.$digest(); 
    })); 

    it('should get the language array', function() { 
     spyOn(translationService, 'getLanguages'); 
     createController(); 
     expect(translationService.getLanguages).toHaveBeenCalled(); 
    }); 
}); 

,這是控制器:

dictControllers.controller('LanguageCtrl', ['$scope', 'translationService', function($scope, translationService){ 


     $scope.getLanguages = function() { 
      translationService.getLanguages().then(function(){ 
       $scope.languages = translationService.languages; 
      }); 
     }; 

     $scope.getLanguages(); 

     $scope.getWords = function(language) { 
      translationService.getWords(language); 
     }; 


     $scope.newWord = {}; 

     $scope.addWord = function(language) { 
      translationService.addWord($scope.newWord, language); 
      $scope.newWord = {}; 
      }; 

    }]); 

回答

4

使用spyOn(mockTranslationService, 'getLanguages').and.returnValue(deferred.promise);代替。在調用getLocations()之後而不是在getLocations()返回承諾之前解決承諾也更有意義。您還應該檢查語言。

inject(function($q) { 
    deferred = $q.defer(); 

    mockTranslationService.languages = [ 
     { 
      name: 'slovak' 
     }, 
     { 
      name: 'czech' 
     } 
    ]; 

    mockTranslationService.languagesWithWords = [{ 
     name: 'slovak', 
     words: [{ 
      key: 'Car', 
      translation: 'Auto', 
      createdOn: 0 
     }, { 
      key: 'Flower', 
      translation: 'Kvet', 
      createdOn: 0 
     }] 
    }, { 
     name: 'czech', 
     words: { 
      key: 'Plaza', 
      translation: 'Namesti', 
      createdOn: 0 
     } 
    }]; 

    mockTranslationService.getLanguages = function() { 
    }; 

    spyOn(mockTranslationService, 'getLanguages').and.returnValue(deferred.promise); 

}); 

it('should get the language array', function() { 
    createController(); 

    deferred.resolve(); 
    scope.$digest(); 

    expect(translationService.getLanguages).toHaveBeenCalled(); 
    expect(scope.languages).toEqual(translationService.languages); 
}); 

Plunkr

+0

感謝您的回答。它現在通過了測試,但我不太清楚它是如何工作的。當你解決承諾沒有任何數據通過它,如何可能的scope.languages === mockService語言? – 2015-02-09 13:51:24

+0

我解決了沒有任何數據的承諾,因爲您的控制器實際上沒有對數據做任何事情。你的控制器很奇怪。通常在你的控制器中你會做:'translationService.getLanguages()。then(function(data){scope = lang.sql = data; });'' – 2015-02-09 13:54:48