AngularJS Karma 单元测试
AngularJS Karma Unit Testing
只是在摆弄 moviedb api 并尝试为我的 navigateGenre 函数编写测试,但我不断收到错误消息:
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];
}
};
}]);
如有任何帮助,我们将不胜感激。
如果我需要添加任何内容,请告诉我。
终于能够让这个东西工作了。
我所做的是将 $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);
}));
});
只是在摆弄 moviedb api 并尝试为我的 navigateGenre 函数编写测试,但我不断收到错误消息:
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];
}
};
}]);
如有任何帮助,我们将不胜感激。 如果我需要添加任何内容,请告诉我。
终于能够让这个东西工作了。
我所做的是将 $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);
}));
});