在Karma单元测试中未解决Angular $ q.when

Yoo*_*rek 10 jasmine angularjs karma-runner

我使用$ q.when来包装其他lib promises.它就像一个魅力,但是当我尝试在Karma中运行它时,即使我运行$ digest甚至超时后,promise仍然会解决(done()永远不会被执行).这是示例代码:

describe('PouchDB', function () {
var $q, $rootScope;

beforeEach(inject(function (_$rootScope_, _$q_) {
    $rootScope = _$rootScope_;
    $q = _$q_;
}));

it("should run", function (done) {

    function getPromise() {
        var deferred = Q.defer();

        deferred.resolve(1);

        return deferred.promise;
    }

    $q.when(getPromise())
        .then(function () {
            done();   // this never runs
        });

    $rootScope.$digest();
});
Run Code Online (Sandbox Code Playgroud)

为什么?这是什么原因?我真的无法得到它.

更新(解决方法)

我不明白为什么$ q.when在Karma中没有得到解决 - 它有nextTick功能,但我无法调试问题.相反,我放弃了$ q.when并编写了简单的函数,将PouchDB(或任何其他类似的Q)转换为$ q:

.factory('$utils', function ($q, $rootScope) {
  return {
    to$q: function (promise) {
      var deferred = $q.defer();

      promise.then(function (result) {
        deferred.resolve(result);
        $rootScope.$digest();
      });

      promise.catch(function (error) {
        deferred.reject(error);
        $rootScope.$digest();
      });

      return deferred.promise;
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

And*_*gee 21

如何解决Jasmine单元测试中的$ q.all承诺?似乎诀窍是:

$rootScope.$apply();
Run Code Online (Sandbox Code Playgroud)

我遇到了同样的问题,这对我有用; 做出这个电话的承诺得到了解决.


MBi*_*ski 1

我已经调整了变量并注入了依赖项名称,以便在测试编写继续时保持清晰。如果done()是(控制器?指令?服务/工厂?)内部的函数,那么应该在测试运行时调用它,而不尝试将其作为依赖项传递。理想情况下,done() 应该被监视,但是如果不知道它来自哪里,就不可能向您展示如何设置监视函数。

唯一缺少的其他细节是您在此测试套件中没有 Expect() 。没有它,我无法知道您期望断言什么。

describe('PouchDB', function () {
    var scope, db, q, rootScope;

    beforeEach(
        inject(
            function(_$rootScope_, _$q_){
                rootScope = _$rootScope_;
                scope = rootScope.$new();
                q = _$q_;
            }
        )
    );

    it("should run", function(){

        //spy should be constructed here

        function getPromise() {
            var deferred = q.defer();

            deferred.resolve(1);

            return deferred.promise;
        }

        q.when(getPromise)
            .then(function () {
                done();
            });

        scope.$digest();

        //assertion should be here

    });
});
Run Code Online (Sandbox Code Playgroud)