0

我有一个用角度编写的服务“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();
    });
}

上面的代码没有解决这个承诺。

我已经尝试过,添加一个 afterEach 来执行 $rootScope.$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.

至少在这种情况下,promise 正在得到解决。但是在该测试用例完成后它会被解决,这会导致测试用例失败。

任何想法,如何解决这个问题

解决方案:

我找到了解决方案。诀窍是在服务本身中使用 $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();
    });

});
4

0 回答 0