Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular $q.when is not resolved in Karma unit test

I use $q.when to wrap around other lib promises. It works like a charm but when i try to run it inside Karma the promise failes to resolve (done() is never executed) even if I ran $digest and even after timeout. Here is sample code:

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();
});

Why? What is the cause of this? I really cannot get it.

Update (workaround)

I do not understand why $q.when is not resolved in Karma - it has something with nextTick function but I cannot debug the problem. Instead I ditched $q.when and wrote simple function that converts PouchDB (or any other like Q) to $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;
    }
  }
})
like image 340
Yoorek Avatar asked Jun 13 '14 18:06

Yoorek


People also ask

What is Q defer () in Angular JS?

Simply put you can use $q. defer() to create a Promise. A Promise is a function that returns a single value or error in the future. So whenever you have some asynchronous process that should return a value or an error, you can use $q. defer() to create a new Promise.

What is the use of karma in Angular?

Karma handles the process of creating HTML files, opening browsers and running tests and returning the results of those tests to the command line. If you use the Angular CLI to manage projects it automatically creates stub Jasmine spec files for you when generating code.

How is unit testing done in Angular?

To run the test, you will only need to run the command ng test . This command will also open Chrome and run the test in watch mode, which means your test will get automatically compiled whenever you save your file. In your Angular project, you create a component with the command ng generate component doctor .


1 Answers

From How to resolve $q.all promises in Jasmine unit tests? it seems the trick is:

$rootScope.$apply();

I just had the same problem and this works for me; the promises are resolved on making this call.

like image 142
Andrew Magee Avatar answered Oct 25 '22 12:10

Andrew Magee