我有一个服务' dbService'用角度写的。
devlog.service('dbService', ['$q', function($q) {
this.getLogs = function() {
var deferred = $q.defer();
db.find({}, function(err, docs) {
if(!err) {
deferred.resolve(docs);
} else {
deferred.reject(err);
}
});
return deferred.promise;
}
}
以上代码从数据库(nedb)获取数据。它只是一个围绕nedb的api的包装,它返回了一个承诺。
单元测试的想法是在不进行任何xhr或db调用的情况下测试逻辑。
在我的情况下,我如何做到这一点?
我已经尝试过以下方式进行测试,假设我们违反了上述关注点分离法则。
describe("DevLog Services", function() {
var dbService;
var $rootScope;
beforeEach(module('devLog'));
beforeEach(inject(function(_$rootScope_, _dbService_) {
$rootScope = _$rootScope_;
dbService = _dbService_;
}));
it('should work', function(done) {
var promise = dbService.getLogs();
promise.then(function(logs) {
console.log('yipee' + logs);
expect(logs).toBeDefined();
});
$rootScope.$apply();
done();
});
}
上述代码并未解决承诺。
我试过了,添加了一个执行$ rootScope的afterEach。$ apply();
afterEach(function() {
$rootScope.$apply();
}
it('should work', function(done) {
var promise = dbService.getLogs();
var allLogs;
promise.then(function(logs) {
allLogs = logs;
console.log(allLogs);
done();
});
$rootScope.$apply();
expect(allLogs).toBeDefined();
});
在这种情况下,我收到此错误Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
。
至少在这种情况下,承诺正在得到解决。但是在测试用例完成后解决了,这导致测试用例失败。
任何想法,如何解决此问题
解决方案:
我找到了解决方法。诀窍是在服务本身中使用$ rootScope。$ apply()。
devlog.service('dbService', ['$q', '$rootScope', function($q, $rootScope) {
this.getLogs = function() {
var deferred = $q.defer();
db.find({}, function(err, docs) {
if(!err) {
deferred.resolve(docs);
} else {
deferred.reject(err);
}
$rootScope.$apply();
});
return deferred.promise;
}
}
并在测试中
it('should work', function(done) {
var promise = dbService.getLogs();
var allLogs;
promise.then(function(logs) {
expect(logs).toBeDefined();
expect(logs.length).toBeGreaterThan(0);
done();
});
});