I am reading some tutorials on promise tests in mocha. There is a piece of codes:
before(function(done) {
return Promise.resolve(save(article)).then(function() {
done();
});
});
Why done()
called in the then()
in the before()
? What is the difference between the above codes and the following codes:
before(function(done) {
return Promise.resolve(save(article));
});
Thanks
UPDATE
My question is to compare with the following codes:
before(function() {
return Promise.resolve(save(article));
});
Sorry for the typo.
A promise is an object that may produce a single value some time in the future : either a resolved value, or a reason that it's not resolved (e.g., a network error occurred). A promise may be in one of 3 possible states: fulfilled, rejected, or pending.
as long as the sun rises at dawn each day. I promise to love you as long as you smile at me in your special way. I promise to give you some time on your own so to your own self be true. I promise to give you my help and support always, in all that you do.
Promises are an affirmation of love, friendship, family and human connection. Actions speak louder than words. Promises are actions that affirm our love and connection with others. Whether that connection is through friendships, family or strangers, promises affirm that we want to pass on our compassion to others.
A promise is simply an object that we create like the later example. We instantiate it with the new keyword. Instead of the three parameters we passed in to make our car (color, type, and doors), we pass in a function that takes two arguments: resolve and reject .
The first code snippet with the before
hook returns a promise and calls done
. In Mocha 3.x and over, it will result in this error:
Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.
It used to be that it did not particularly matter if you used done
and returned a promise, but eventually the Mocha devs figured that specifying both done
and returning a promise just meant the test designer made a mistake and it was better to have Mocha pitch a fit rather than silently allow it.
In your 2nd snippet, you have the done
argument and return a promise but Mocha will still wait for done
to be called and will timeout. (It really should detect the argument and raise an error like in the 1st case, but it doesn't...)
Generally, if you are testing an asynchronous operation that produces a promise, it is simpler to return the promise than use done
. Here's an example illustrating the problem:
const assert = require("assert");
// This will result in a test timeout rather than give a nice error
// message.
it("something not tested properly", (done) => {
Promise.resolve(1).then((x) => {
assert.equal(x, 2);
done();
});
});
// Same test as before, but fixed to give you a good error message
// about expecting a value of 2. But look at the code you have to
// write to get Mocha to give you a nice error message.
it("something tested properly", (done) => {
Promise.resolve(1).then((x) => {
assert.equal(x, 2);
done();
}).catch(done);
});
// If you just return the promise, you can avoid having to pepper your
// code with catch closes and calls to done.
it("something tested properly but much simpler", () => {
return Promise.resolve(1).then((x) => {
assert.equal(x, 2);
});
});
With regards to the completion of asynchronous operations, it works the same whether you are using it
, before
, beforeEach
, after
or afterEach
so even though the example I gave is with it
, the same applies to all the hooks.
I am not sure if I understood 100% the question, but the tests will not start until done
is called.
beforeEach(function(done) {
setTimeout(function() {
value = 0;
done();
}, 1);
});
This test will not start until the done function is called in the call to beforeEach above. And this spec will not complete until its done is called.
it("should support async execution of test preparation and expectations", function(done) {
value++;
expect(value).toBeGreaterThan(0);
done();
});
You don't have to pass done in your example, just:
before(function() {
return Promise.resolve(save(article));
});
If you do pass done
the test runner will expect to be called before continue, otherwise it will probably throw a timeout error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With