Using await / async with mocha, chai


I'm quite new to node and express. And have been trying to write test code using mocha, chai and chai-http. Here's the part of source code.

const mongoose = require('mongoose'), User = require('../../models/user'); const mongoUrl = 'mongodb://xxxxxxxxxxx'; describe('/test', function() { before('connect', function() { return mongoose.createConnection(mongoUrl); }); beforeEach(async function(done) { try { await User.remove({}); // <-- This doesn't work chai.request('http://localhost:3000') .post('/api/test') .send(something) .end((err, res) => { if (err) return done(err); done(); }); } catch (error) { done(error); } }); });

And I get the following error with "npm test"(nyc mocha --timeout 10000 test/**/*.js).

Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

I confirmed the database connection works properly from log. And seems I get the timeout error with await User.remove({}). I've also tried different methods such as a User.save() But, I got the same error. Do I need to do something special with database model and connection?


I had the same problem and have not found a way to get any promises that involve mongoose working with Mocha/Chai.

What may help you is doing what I did and putting your mongoose code in a script so you can run it with node <scriptfile>.js. You can use that to confirm it's working properly by itself. In my test, the mongoose operation finished in less than a second. You can also call that file from another (non-test related) to confirm it executes properly and returns a promise. You can see from my example how to make sure you close db properly. Partial example:

... db.close(); return new Promise((resolve) => { db.on('disconnected', () => { console.log('***************************************Mongoose CONNECTION TERMINATED'); resolve('user ready'); }); }); ...

You may also find some clues by looking at the following issues here and here.

The work around that I did after wasting too much time trying to figure out this crazy behavior was to perform my mongoose needs in a route. I wrap each request that needs to use it in the end block of the extra chai.request... or use async. Example:

describe('something', () => { it('should do something and change it back', async () => { try { // change user password let re1 = await chai.request(app) .post('/users/edit') .set('authorization', `Bearer ${token}`) .send({ username: 'user@domain.com', password: 'password6', }); expect(re1.statusCode).to.equal(200); // change password back since before hook not working let re2 = await chai.request(app) .post('/users/edit') .set('authorization', `Bearer ${token}`) .send({ username: 'user@domain.com', password: 'password6', passwordNew: 'password', passwordConfirm: 'password', }); expect(re2.statusCode).to.equal(200); } catch (error) { // error stuff here } });

Note that using the try/catch syntax above will cause test that should normally fail to show passing and the results will be caught in the catch block. If you want to avoid that, just remove the try/catch.


How did you implement ./models/user? await only works if User.remove() returns a promise, not if it expects a callback. I would add debug information to your User.remove() function to see where it gets stuck.


This is all pretty simple.

To avoid the error you must not use both done and async/await in Mocha at the same time. Either use async/await and remove both done as function parameter and done() call. Or use done. Then remove both async/await. See example test below for both.

Use try/catch with async/await as you would normally use it with synchronous code.

Following are the most basic Mocha tests with both async/await and done approaches testing the same basic HTTP server endpoint.

This is async/await approach.

<pre class="lang-js prettyprint-override">it('with async/await', async function() { const res = await chai.request(server) .get('/') .send(); assert.equal(res.status, 200); });

This is done approach.

<pre class="lang-js prettyprint-override">it('with done & callbacks', (done) => { chai.request(server) .get('/') .end((err, res) => { assert.equal(res.status, 200); done(); }); });

See the full test file snippet.

For working example additionally spin most basic Express server as the tests counterpart in src/app.js.

See Chai HTTP plugin docs for more info on what you can do with request testing.

This is it.



  • NSDictionary getting sorted alphabetically [duplicate]
  • display all elements in a nested cell array (with character entries)
  • application not installing on android emulator
  • Can not open created raster in R
  • Cloud Foundry Bind services/cups datasource number of connections
  • Getting SPI temperature data from outside of class
  • Firebase Cloud Messaging: how to send data message to all users? [duplicate]
  • problem parsing with XMLReader (using ReadSubTree)
  • SVG animation not working in Chrome (using animateTransform in GWT)
  • Parse fasta sequence to the dictionary
  • get value using jquery
  • limit python input to int
  • Javapackager tool from command-line on OSX?
  • How do I get the standard Vim FTP command to work?
  • Semi-local Levenshtein distance
  • Can I switch the 'connected' user within an sql script that is sourced by mysql?
  • Gitlab: copy project to other git lab repository
  • Generate a runnable jar and include libraries in it with Maven
  • VS2010: Ctrl-PgUp / -PgDown like in browsers
  • Protractor Page objects - TypeError: Object # has no method 'methodName'
  • Issue with Terrain Collision using Three.js
  • Unable to start a WebView from an AsyncTask
  • How to output data of primefaces DataGrid component by columns instead of by rows (transpose data)?
  • .Net core Hosted Services guaranteed to complete
  • opencv deskewing a contour
  • How to define a custom accuracy in Keras to ignore samples with a particular gold label?
  • C# code can't “see” the methods in my C++ dll
  • flex tree gets chopped even after using scroll bar
  • How to use array in autohotkey?
  • How to redirect into different page by user type in php and mysql
  • Generate and export point cloud from Project Tango
  • All Event listing on specified date in Google Calender api (V3) in java?
  • How to run chrome.tabs.insertCSS from the background page on each page?
  • PHPMailer return to AJAX
  • Floating parent div grows to hypothetical width of floating child div
  • How to make 100% div height between header and footer?
  • JavaScript Regex to Match Boundaries of Words with diacritics
  • How to turn off notice reporting in xampp?
  • Stacked bar chart with continuous time-axis as x-axis
  • Jersey serializes character value to ASCII equivalent numeric string