Joshua Ohana
Joshua Ohana

Reputation: 6121

Jasmine resolving promises after calls but before expects

For testing my controller I have some services mocked out using $q injection. These will reject or resolve the promises where appropriate. My tests rely on spies to monitor if functions have been called.

I've found all over that I need to call $rootScope.$digest() which works if I include it in the test after the function call, but it's redundant and I'm afraid I might forget it in tests sometimes.

If I try to move the digest call to an afterEach, the promises aren't actually resolved!

Trying to use the below, which is nested in the parent of the test with all of my beforeEachs:

afterEach(function () {
    $rootScope.$apply();
});

Then my test, which in a describe in the same scope as my before/afterEachs:

it("on return success from personService.add, state.go called", function () {
            $scope.addPerson(true);
            expect($state.go).toHaveBeenCalled();
        });

If I run as is above, the function is not called. However, if I add a $rootScope.$digest() after my call to addPerson it is called!

1) How can I globally resolve promises after a function call but before my expects

Upvotes: 0

Views: 113

Answers (1)

Omri Aharon
Omri Aharon

Reputation: 17064

The each in the afterEach/beforeEach refers to the it method. That means you can't expect to call a function in the it part, digest the scope in the afterEach and still have your expect in the it method.

If you're afraid you'll forget to run the digest you can wrap up your function calls in a private function in the spec that will take care of it for you, something like that:

describe(...., function () {
    ....
    function doAct(func) {
        if (typeof func === "Function") {
            func();
            $rootScope.$digest();
        }
    }

    // it methods here
});

And simply have a wrapper call for those specific spec tests:

it("on return success from personService.add, state.go called", function () {
      doAct(function () {
          $scope.addPerson(true);
      });
      expect($state.go).toHaveBeenCalled();
});

I must say I don't think it's that big an overhead to do the digest call, and you might be having more trouble with what I'm suggesting above if other programmers take your code without understanding what it does.

Upvotes: 1

Related Questions