【发布时间】:2016-06-16 17:14:18
【问题描述】:
我使用 Karma + Jasmine 为 Angular 项目编写单元测试。
我正在尝试测试一个通过承诺返回正确结果的 Angular 服务。以下是我目前所拥有的。
项目服务
'use strict';
var app = app || {};
app.factory('ProjectSvc', ['$http', '$q', function($http, $q) {
var project_url = 'https://dl.dropboxusercontent.com/u/2122820/hosted_json/project.json';
var svc = {};
svc.cachedProjects = [];
svc.getProjects = function() {
return $http.get(project_url);
}
function lookUp(slug) {
for (var i=0; i < svc.cachedProjects.length; i++){
if (svc.cachedProjects[i].slug && svc.cachedProjects[i].slug == slug) {
return svc.cachedProjects[i];
} else if (svc.cachedProjects[i].title == slug) {
return svc.cachedProjects[i];
}
}
return null;
}
//return a promise
svc.retrieveProjectById = function(id) {
var deferred = $q.defer();
if (svc.cachedProjects.length > 0 ) {
var found = lookUp(id);
if (!found) {
deferred.reject ({error: 'not found', data: null});
} else {
deferred.resolve(found);
}
} else {
init().then(function(data){
//console.log('---------');
svc.cachedProjects = data.data.projects;
var found = lookUp(id);
//console.log('found: ', found);
if (!found) {
deferred.reject ({error: 'not found', data: null});
} else {
deferred.resolve(found);
}
})
}
return deferred.promise;
}
//return a promise
svc.retrieveProjectBySlug = function(slug) {
return svc.retrieveProjectById(slug)
}
function init(index) {
console.log('init');
return svc.getProjects().then(function(data) {
svc.cachedProjects = data.data.projects;
});
}
return svc;
}]);
describe('Project Service', function() {
beforeEach(module('myApp'));
var ProjectSvc, $httpBackend;
var $q, $rootScope;
beforeEach(inject(function(_ProjectSvc_, _$httpBackend_, _$q_, _$rootScope_) {
// The injector unwraps the underscores (_) from around the parameter names when matching
ProjectSvc = _ProjectSvc_;
$httpBackend = _$httpBackend_;
$q = _$q_;
$rootScope = _$rootScope_;
spyOn(ProjectSvc, 'retrieveProjectBySlug').and.callFake(function() {
var defer = $q.defer();
defer.resolve();
return defer.promise;
});
}));
describe('.retrieveProjectBySlug()', function() {
it('test promise in service', function() {
var project_url = 'https://dl.dropboxusercontent.com/u/2122820/hosted_json/project.json';
//$httpBackend.expectGET(project_url).respond(200, {data: null});
console.log('-------------');
var project;
ProjectSvc.retrieveProjectBySlug('monopoly-checker').then(function(data) {
project = data;
console.log(project);
$rootScope.$apply();
console.log('project', project);
});
expect(project.length).toBe(1);
});
});
});
http://stackoverflow.com/questions/ask#
运行karma start,我明白了:
1) test promise in service
Project Service .retrieveProjectBySlug()
TypeError: Cannot read property 'length' of undefined
似乎承诺永远不会得到解决,因此project 始终未定义。你能解决这个问题吗?
如果有帮助,完整的源代码在https://github.com/rattanakchea/rattanakchea.github.io/tree/test
【问题讨论】:
-
你的期望在 promise 被解决之前运行,因此它是未定义的?
标签: angularjs testing jasmine karma-runner