My unit test is not working hitting the then
function for some reason. Here is the test code.
describe("Basic promise test", () => {
it("should trigger .then function", () => {
var mock = jasmine.createSpy('some method');
var promise = new Promise((resolve, reject)=> {
console.log("inside Promise");
resolve('something');
console.log("done!");
});
promise.then(mock);
promise.then(function () { //neither works!
mock();
console.log("resolved"); //code does reach here but only after test fails
});
expect(mock).toHaveBeenCalled();
});
});
I've tried using 'babel-polyfill', 'es6-promise' and 'promise-polyfill' to no avail. What am I doing wrong?
Jsfiddle for this: /
My unit test is not working hitting the then
function for some reason. Here is the test code.
describe("Basic promise test", () => {
it("should trigger .then function", () => {
var mock = jasmine.createSpy('some method');
var promise = new Promise((resolve, reject)=> {
console.log("inside Promise");
resolve('something');
console.log("done!");
});
promise.then(mock);
promise.then(function () { //neither works!
mock();
console.log("resolved"); //code does reach here but only after test fails
});
expect(mock).toHaveBeenCalled();
});
});
I've tried using 'babel-polyfill', 'es6-promise' and 'promise-polyfill' to no avail. What am I doing wrong?
Jsfiddle for this: https://jsfiddle/L53zxe39/
Share Improve this question edited Jun 23, 2016 at 14:02 supersan asked Jun 23, 2016 at 13:53 supersansupersan 6,1813 gold badges49 silver badges71 bronze badges 3-
The promise resolves asynchronously, so you need to use jasmine's async testing features. According to this article and this SO answer, that involves using
runs
andwaitsFor
. I'd post it as an answer, but I know nothing about jasmine, maybe there's something more specific for promise testing thanruns
andwaitsFor
. – T.J. Crowder Commented Jun 23, 2016 at 14:02 -
@T.J.Crowder please see the jsfiddle here: jsfiddle/L53zxe39. I've already tried using
waitsFor
but it throws an error because I'm using Jasmine 2.0 (i think they've removed it) – supersan Commented Jun 23, 2016 at 14:03 - Yeah, that's why I didn't post an answer, I just don't know jasmine, couldn't tell the age of the article, and the answer I found was from 2013 before promises were really big. But fundamentally, the issue is that the resolution is async, so jasmine needs to know that. So look at the jasmine docs for the current way to test promise-based APIs. – T.J. Crowder Commented Jun 23, 2016 at 14:04
1 Answer
Reset to default 9The promise is resolved, but the then
callback is only called in the next microtask, after the check expect(mock).toHaveBeenCalled();
has been made.
It is intended behaviour and designed to prevent ambiguity around promises. A .then
callback is guaranteed to be called later, even if the promise is already resolved.
Asynchronous jasmine tests work in the following way:
describe("Basic promise test", () => {
it("should trigger .then function", (done) => {
var mock = jasmine.createSpy('some method');
var promise = new Promise((resolve, reject)=> {
console.log("inside Promise");
resolve('something');
console.log("done!");
});
promise.then(mock).then(() => {
expect(mock).toHaveBeenCalled();
done();
}).catch(e => {
done.fail(e);
});
});
});
You can use done.fail
to explicitly fail the spec. This is needed to catch and notify jasmine about uncaught exceptions during tests.