Reputation: 1151
I've got some mocha tests that require data from prior function calls. However, because my code is using a web service, I would like it to wait for a predetermined amount of time before running the next test.
Something like this:
var global;
it('should give some info', function(done) {
run.someMethod(param, function(err, result) {
global = result.global
done();
});
});
wait(30000); // basically block it from running the next assertion
it('should give more info', function(done) {
run.anotherMethod(global, function(err, result) {
expect(result).to.be.an('object');
done();
});
});
Any ideas would be appreciated. Thanks!
Upvotes: 25
Views: 64629
Reputation: 4145
In my case, I was coding a RESTful API
in NodeJS
that was manipulating some files locally. As I was launching the tests, the API was receiving multiple requests and it makes my API manipulate, concurrently, these files in the machine, which led me to a problem.
So, I needed to put some time (1 sec
was enough) between these API calls. For me, the solution was the following one:
beforeEach( async () => {
await new Promise(resolve => setTimeout(resolve, 1000));
console.log("----------------------");
});
Now, before each it()
test, the previous function is run, and I have a sleep of 1 second between API calls.
Upvotes: 15
Reputation: 1420
setTimeout
definitely could help, but there may be a "cleaner" way to do it.
The documentation here actually says to use this.timeout(delay)
to avoid timeout errors while testing async code, so be careful.
var global;
it('should give some info', function(done) {
run.someMethod(param, function(err, result) {
global = result.global
done();
});
});
it('should give more info', function(done) {
this.timeout(30000);
setTimeout(function () {
run.anotherMethod(global, function(err, result) {
expect(result).to.be.an('object');
done();
});
}, 30000);
});
Upvotes: 29
Reputation: 6916
First:
This thread has great answers! I personally Liked @Flops answer (got my upvote)
Second:
To clarify this (as much as possible) here is a code sample very similar to the one I ended up with (tested and verified)
function delay(interval)
{
return it('should delay', done =>
{
setTimeout(() => done(), interval)
}).timeout(interval + 100) // The extra 100ms should guarantee the test will not fail due to exceeded timeout
}
it('should give some info', function(done) {
run.someMethod(param, function(err, result) {
global = result.global
done();
});
});
delay(1000)
it('should give more info', function(done) {
run.anotherMethod(global, function(err, result) {
expect(result).to.be.an('object');
done();
});
});
Side note: you can also use delay functions one after another and still preserve consistency (tests order)
Upvotes: 5
Reputation: 2597
Here's another, using promises:
it('go, then stop', (done) => {
// this.skip();
go()
.then((response) => { console.log('go was called'); return response; })
.then(response => response.should.equal('acknowledged'))
.then(() => new Promise(resolve => setTimeout(() => { resolve(); }, 3000)))
.then(() => console.log('3 second wait is over'))
.then(() => stop())
.then(response => response.should.equal('acknowledged'))
.then(() => done());
}).timeout(15000);
Upvotes: 1
Reputation: 1908
First of all, for proper unit testing, you should never need some sleep between tests. If you do need a sleep, this means the functions you are testing require a delay before completing its expected task, which must be handled inside that function, with some asynchronous wait or sleep. Upon exit from a function, its lifetime must end and the expected result must be acquired immediately.
Upvotes: 0
Reputation: 19569
While this.timeout()
will extend the timeout of a single test, it's not the answer to your question. this.timeout()
sets the timeout of your current test.
But don't worry, you should be fine anyway. Tests are not running in parallel, they're done in series, so you should not have a problem with your global approach.
Upvotes: 10