2

I have a test that requires one promise to be run and later in its then handler another promise returning function is run.

The first promise resolves, and a successful call is made to the next function which returns a promise. However, the then handler for that second promise never fires.

Is there another way to test nested promises using Jasmine 2.0?

Example problem:

describe("nested promise suite", function () {
        var prom1 = function () {
            var deferred = $q.defer();
            $timeout(function () {
                deferred.resolve('prom1');
            }, 500)
            return deferred.promise;
        };

        var prom2 = function () {
            var deferred = $q.defer();
            $timeout(function () {
                deferred.resolve('prom2');
            }, 500);
            return deferred.promise;
        };

        iit("nested promise test", function (done) {
            prom1()
                .then(function (result) {
                    console.log('prom1 result ', result);
                    prom2()
                        .then(function (result2) {
                            console.log('prom2 result ', result2);
                        })
                        .finally(function() {
                            console.log('you did it');
                        })
                })
                .finally(done);  //this causes promise one to resolve properly but unsure of how to make the second promise resolve properly
            $timeout.flush();
        })
    });
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
binarygiant
  • 6,362
  • 10
  • 50
  • 73
  • You should always `return` your promises from `then()` callbacks. – Bergi Mar 03 '15 at 12:36
  • Don't use the [deferred antipattern](http://stackoverflow.com/q/23803743/1048572)! [`$timeout`](https://docs.angularjs.org/api/ng/service/$timeout) already returns a promise. – Bergi Mar 03 '15 at 12:38

1 Answers1

1

I'm not sure if this is the problem in your original code as well, but in this example, your second console.log doesn't fire because prom2 adds a new timeout after the first has been flushed. The promise from prom2 then waits for this new timeout to flush, which never happens:

  1. prom1() is called
  2. The first promise and timeout are created
  3. The first timeout is flushed, resolving the first promise
  4. The then() block is triggered, calling prom2()
  5. The second promise and timeout are created
  6. done() is called.

You can try adding a second $timeout.flush(); call right after the one that's already there, which will flush the second timeout, resolve the second promise, and log the missing messages.

Spiny Norman
  • 8,277
  • 1
  • 30
  • 55