2016-03-05 177 views
0

剛剛與moviedb API瞎搞,我試圖寫一個測試我navigateGenre功能,但我不斷收到錯誤:AngularJS噶單元測試

TypeError: Cannot read property 'id' of undefined

這裏是規範和控制代碼:

規格:

describe('Genre List Controller', function(){ 
    var ctrl, scope; 

    beforeEach(module('MovieFinder')); 

    beforeEach(inject(function($controller, $route, $rootScope, _$location_, _GenreListFactory_){ 
     scope = $rootScope.$new(); 
     var $location = _$location_; 
     var GenreListFactory = _GenreListFactory_; 

     $route.current = { 
      params: { 
       genreId: 18 
      } 
     }; 

     ctrl = $controller('GenreListCtrl', { 
      $scope: scope, 
      $location: $location, 
      GenreListFactory: GenreListFactory, 
      $route: $route 
     }); 
    })); 

    fit('should route to correct genre when navigateGenre() is called', 
    inject(function($httpBackend, $rootScope, $route, $location){ 
     $httpBackend.expect('JSONP', 'http://api.themoviedb.org/3/genre/movie/list?api_key=&callback=JSON_CALLBACK').respond(200); 
     $httpBackend.expect('GET', 'js/genre-detail/genre-detail.html').respond(200); 

     $rootScope.$apply(function(){ 
      $location.path('/genre/18'); 
     }); 

     $rootScope.$apply(function(){ 
      scope.navigateGenre(); 
     }); 

     expect($route.current.originalPath).toBe('/genre/:genreId'); 
     expect($route.current.params.genreId).toBe(); 

    })); 
}); 

控制器:

MovieFinder 
    .controller('GenreListCtrl', ['$scope', '$route', '$location', 'GenreListFactory', function($scope, $route, $location, GenreListFactory){ 
     GenreListFactory().then(function(genres){ 
      console.log('GenreListCtrl', genres); 
      $scope.test = 'test'; 
      $scope.genreList = [{id: null, name: 'Select a Genre'}]; 
      genres.data.genres.forEach(function(genre){ 
       //console.log(genre.name); 
       $scope.genreList.push(genre); 
      }); 
      $scope.selectedGenre = $scope.genreList[0]; 
     }); 
     $scope.navigateGenre = function(){ 
      if($scope.selectedGenre.id !== null){ 
       $location.path('genre/' + $scope.selectedGenre.id); 
       $scope.selectedGenre = $scope.genreList[0]; 
      } 
     }; 
    }]); 

任何幫助,將不勝感激。 讓我知道如果我需要包括任何東西。

+0

據我可以注意到。 你應該嘗試用一些模擬數據先解決承諾,然後只有你的$ scope.genreList和$ scope.selectedGenre會被初始化。您正在調用navigationGenre函數,但$ scope.selectedGenre未在任何地方初始化。 – Diljohn5741

+0

@ Diljohn5741感謝您的建議,我會嘗試,看看我能否得到它的工作 –

回答

0

終於能夠得到這個東西的工作。 我所做的是將$scope.genreList and $scope.selectedGenre移出.then()。 $httpBackend.expect設置爲響應200,但如果我們不模擬延期承諾並解決它,.then將永遠不會觸發。

這裏是重構的代碼:

控制器:

MovieFinder 
    .controller('GenreListCtrl', ['$scope', '$route', '$location', 'GenreListFactory', function($scope, $route, $location, GenreListFactory){ 
     $scope.genreList = [{id: null, name: 'Select a Genre'}]; 
     $scope.selectedGenre = $scope.genreList[0]; 

     GenreListFactory().then(function(genres){ 
      console.log('GenreListCtrl', genres); 
      $scope.test = 'test'; 
      genres.data.genres.forEach(function(genre){ 
       //console.log(genre.name); 
       $scope.genreList.push(genre); 
      }); 
      console.log('genreList', $scope.genreList); 
     }); 
     console.log('genreList', $scope.genreList); 
     $scope.navigateGenre = function(){ 
      if($scope.selectedGenre.id !== null){ 
       $location.path('genre/' + $scope.selectedGenre.id); 
       $scope.selectedGenre = $scope.genreList[0]; 
      } 
     }; 
    }]); 

規格:

describe('Genre List Controller', function(){ 
     var ctrl, scope; 

     beforeEach(module('MovieFinder')); 

     beforeEach(inject(function($controller, $route, $rootScope, _$location_, _GenreListFactory_){ 
      scope = $rootScope.$new(); 
      var $location = _$location_; 
      var GenreListFactory = _GenreListFactory_; 

      $route.current = { 
       params: { 
        genreId: 18 
       } 
      }; 

      scope.selectedGenre = { 
       id: 80, 
       name: 'Crime' 
      }; 

      ctrl = $controller('GenreListCtrl', { 
       $scope: scope, 
       $location: $location, 
       GenreListFactory: GenreListFactory, 
       $route: $route 
      }); 
     })); 

     it('should route to correct genre when navigateGenre() is called', 
     inject(function($httpBackend, $rootScope, $route, $location){ 
      $httpBackend.expect('JSONP', 'http://api.themoviedb.org/3/genre/movie/list?api_key=990ba45b90f56c57b4e00a54fc773d8c&callback=JSON_CALLBACK').respond(200); 
      $httpBackend.expect('GET', 'js/genre-detail/genre-detail.html').respond(200); 

      $rootScope.$apply(function(){ 
       $location.path('/genre/18'); 
      }); 

      $rootScope.$apply(function(){ 
       /*scope.selectedGenre.id = 80;*/ 
       scope.navigateGenre(); 
      }); 

      expect($route.current.params.genreId).toBe('18'); 
      expect(scope.selectedGenre.id).toBe(null); 

     })); 
    });