I'm trying to test a service that I build which uses Angular's $q implementation of Promises. I'm using a combination of Karma, Mocha, Chai, Sinon, Sinon Chai and Chai as Promised.
All the tests that I wrote and return promises are passing but the ones that reject or uses $q.all([ ... ])
. I have tried all I could think of but I cannot seem to find where the issue is.
The following is a slim version of what I am testing:
"use strict";
describe("Promise", function () {
var $rootScope,
$scope,
$q;
beforeEach(angular.mock.inject(function (_$rootScope_, _$q_) {
$rootScope = _$rootScope_;
$q = _$q_;
$scope = $rootScope.$new();
}));
afterEach(function () {
$scope.$apply();
});
it("should resolve promise and eventually return", function () {
var defer = $q.defer();
defer.resolve("incredible, this doesn't work at all");
return defer.promise.should.eventually.deep.equal("incredible, this doesn't work at all");
});
it("should resolve promises as expected", function () {
var fst = $q.defer(),
snd = $q.defer();
fst
.promise
.then(function (value) {
value.should.eql("phew, this works");
});
snd
.promise
.then(function (value) {
value.should.eql("wow, this works as well");
});
fst.resolve("phew, this works");
snd.resolve("wow, this works as well");
var all = $q.all([
fst.promise,
snd.promise
]);
return all.should.be.fullfiled;
});
it("should reject promise and eventually return", function () {
return $q.reject("no way, this doesn't work either?").should.eventually.deep.equal("no way, this doesn't work either?");
});
it("should reject promises as expected", function () {
var promise = $q.reject("sadly I failed for some stupid reason");
promise
["catch"](function (reason) {
reason.should.eql("sadly I failed for some stupid reason");
});
var all = $q.all([
promise
]);
return all.should.be.rejected;
});
});
The 3rd, last and the first test are the ones that fail. Actually it does not fail, it just resolves after the timeout is exceeded and I get a Error: timeout of 2000ms exceeded
.
EDIT: I have just tried to test with Kris Kowal's implementation of the promises and it works just fine with that.
P.S. I actually found that there is some time spent somewhere in the bowls of either Mocha, Chai or Chai As Promised and the afterEach
hook gets called later than the timeout.
$scope.$apply()
until after you text the expectations. Can you try calling it just after you resolve/reject the promise? – Purificator$scope.$apply()
inafterEach
could be an issue in case you expect the value of the promises before theafterEach
is run – NoontimeafterEach
for cleanup only. It just didn't occur to me at the point I did it. – Vincenza