faq labelnode node_modules/.bin/mocha --version(Local) and mocha --version(Global). We recommend avoiding the use of globally installed Mocha.I am trying to test my API with mocha & superagent, the thing is, I need to wait for the db to open, then export the app, because the tests require some initialization code that depends on the db.
So, in order to do that, I had to wrap my test code within an async function and call it, but it doesn't run the tests.
// test.js
describe('math', async () => {
it('multiplies', () => {
let result = 2 * 2;
result.should.equal(4);
});
});
const test = async () => {
const should = require('chai').should();
const request = require('supertest');
const path = require('path')
const app = await require(path.resolve('./server'));
describe('math', async () => {
it('adds', () => {
let sum = 1 + 1;
sum.should.equal(2);
});
});
describe('users', async () => {
it('creates a customer', async () => {
let res = await request(app).get('/api/should-404/');
res.status.should.equal(200);
});
});
};
test().catch(console.err);
// server.js
const run = async () => {
const app = express()();
const mongoose = require('mongoose');
await mongoose.connect('mongodb://localhost:27017/speero_test');
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {console.log.bind(console, 'connection :')});
// the line below depends on the db
const initRolesPolicies = require(path.resolve('./initialize/initPolicies'))();
app.listen(port, function () {
console.log('Autotash is running ' + process.env.NODE_ENV.toUpperCase() + ' on port ' + port + ' !');
});
return app;
}
module.exports = run().catch(console.err);
Expected behavior: All tests to run, the multiplication, the addition, and the customer creation.
Actual behavior: Only the multiplication test (the one outside the _test function_) run, the ones inside are completely ignored even though I execute the function at the bottom.
I don't completely like wrapping the test suites inside a function, but I have to await for the app to be returned, I am open for any other approaches to accomplish this. I just need to wait for db to be ready before exporting the app object and running the tests.
Reproduces how often: [100%]
First thing I notice:
const test = async () => { // not OK => using async function...not kosher in this case
// ...
describe('math', async () => { // this is NOT OK either
it('adds', () => {
let sum = 1 + 1;
sum.should.equal(2);
});
});
// ....
};
you shouldn't register any of the following asynchronously:
it/describe/before/after/afterEach/beforeEach, etc.
all hooks should be registered synchronously, otherwise you will get unknown/undefined behavior.
What if I need to do some async functions on before and beforeEach, like cleaning the database for example?
How should I handle that?
Edit:
I misunderstood. I should write the describe(...) outside an asynchronous function, however, what I write inside the describe(...) can be async.
Actually, I think I just found a solution!
// test.js
const should = require('chai').should();
const request = require('supertest');
const path = require('path')
let app;
before(async () => {
try {
app = await require(path.resolve('./server'));
}
catch (err) {
console.log(err);
}
});
describe('math', async () => {
it('multiplies', () => {
let result = 2 * 2;
result.should.equal(4);
});
it('adds', () => {
let sum = 1 + 1;
sum.should.equal(2);
})
});
describe('users', async () => {
it('creates a customer', async () => {
let res = await request(app).get('/api/should-404/');
res.status.should.equal(200);
});
});
This did the trick after two days of trying to figure it out.
I am completely new to testing, is there a better way to do this?
yep what you have now is good, that is a very common pattern with Mocha. Note that I made a correction to my previous statement. Let me explain better:
// this is bad
describe('foo', async _ => {
it('bar', async done => {
});
});
// this is good
describe('foo', _ => { // remove async from here
it('bar', async done => {
});
});
Thanks a lot!
Most helpful comment
yep what you have now is good, that is a very common pattern with Mocha. Note that I made a correction to my previous statement. Let me explain better: