Error timeout of 2000ms exceeded mocha

You can either set the timeout when running your test: mocha --timeout 15000 Or you can set the timeout for each suite or each test programmatically: describe('

You can either set the timeout when running your test:

mocha --timeout 15000

Or you can set the timeout for each suite or each test programmatically:

describe('...', function(){
  this.timeout(15000);

  it('...', function(done){
    this.timeout(15000);
    setTimeout(done, 15000);
  });
});

For more info see the docs.

I find that the «solution» of just increasing the timeouts obscures what’s really going on here, which is either

  1. Your code and/or network calls are way too slow (should be sub 100 ms for a good user experience)
  2. The assertions (tests) are failing and something is swallowing the errors before Mocha is able to act on them.

You usually encounter #2 when Mocha doesn’t receive assertion errors from a callback. This is caused by some other code swallowing the exception further up the stack. The right way of dealing with this is to fix the code and not swallow the error.

When external code swallows your errors

In case it’s a library function that you are unable to modify, you need to catch the assertion error and pass it onto Mocha yourself. You do this by wrapping your assertion callback in a try/catch block and pass any exceptions to the done handler.

it('should not fail', function (done) { // Pass reference here!

  i_swallow_errors(function (err, result) {
    try { // boilerplate to be able to get the assert failures
      assert.ok(true);
      assert.equal(result, 'bar');
      done();
    } catch (error) {
      done(error);
    }
  });
});

This boilerplate can of course be extracted into some utility function to make the test a little more pleasing to the eye:

it('should not fail', function (done) { // Pass reference here!
    i_swallow_errors(handleError(done, function (err, result) {
        assert.equal(result, 'bar');
    }));
});

// reusable boilerplate to be able to get the assert failures
function handleError(done, fn) {
    try { 
        fn();
        done();
    } catch (error) {
        done(error);
    }
}

Speeding up network tests

Other than that I suggest you pick up the advice on starting to use test stubs for network calls to make tests pass without having to rely on a functioning network. Using Mocha, Chai and Sinon the tests might look something like this

describe('api tests normally involving network calls', function() {

    beforeEach: function () {
        this.xhr = sinon.useFakeXMLHttpRequest();
        var requests = this.requests = [];

        this.xhr.onCreate = function (xhr) {
            requests.push(xhr);
        };
    },

    afterEach: function () {
        this.xhr.restore();
    }


    it("should fetch comments from server", function () {
        var callback = sinon.spy();
        myLib.getCommentsFor("/some/article", callback);
        assertEquals(1, this.requests.length);

        this.requests[0].respond(200, { "Content-Type": "application/json" },
                                 '[{ "id": 12, "comment": "Hey there" }]');
        expect(callback.calledWith([{ id: 12, comment: "Hey there" }])).to.be.true;
    });

});

See Sinon’s nise docs for more info.

If you are using arrow functions:

it('should do something', async () => {
  // do your testing
}).timeout(15000)

In this article I show you how to test asynchronous requests with MochaJS.

To simplify the example I’m going to show you how to build a mock Web server. That way you can simulate the delay from a server, without actually having to run a server.

Step 1. Clone the starter project

Use git to clone my starter repo into a new folder.

git clone https://github.com/mitchallen/autom8able-mochajs-starter.git mocha-async-101

cd mocha-async-101/

npm install

Run the default tests to make sure the install went okay:

npm test

Step 2. Define a mock Web server

In this step I’m going to show you how to create a mock Web server.

I’ll show you how to use a timeout to simulate a delayed asynchronous response.

Replace the contents of src/index.js with this code and I will explain it below:

 // Define a mock Web server class

class MockServer {
  constructor() {
    this.timeout = 100;
    this.result = [
      { id: 'CT', state: 'Connecticut' },
      { id: 'ME', state: 'Maine' },
      { id: 'MA', state: 'Massachusetts' },
      { id: 'NH', state: 'New Hampshire' },
      { id: 'RI', state: 'Rhode Island' },
    ]
  }

  // Define a method to mock a Web server request

  request() {
    // TODO - will cover in next step
  }
}

// Define a factory function

function createMockServer() {
  return new MockServer();
}

// Export factory functions

module.exports = {
  createMockServer
}

The code above does the following:

  • Defines a mock Web server — a class that pretends it’s a Web server
  • Defines a method to mock a Web server request — this will be covered in the next step
  • Defines a factory function — a simplified way to return new objects that I’ve covered before
  • Exports a factory function — a way to export the factory function that I have also covered before

MockServer breakdown

The mock server has two properties whose defaults are set in the constructor:

  • timeout — the length of time to delay the async response (in milliseconds)
  • result — the mock result to return in JSON format

There is no option to pass the parameters during construction. Instead you can overwrite them after you create the object. For example:

var server = mockFactory.createMockServer();
// override defaults 
server.timeout = 1500;
server.result = { status: 200, message: 'Success!' };

Step 3. Fill in the request method

In the class defined above, fill in the method with this code:

request() {
  var _self = this;
  return new Promise( function (resolve, reject) {
    setTimeout( function() {
      resolve( _self.result )
    }, _self.timeout );
  });
}

The request method breakdown

The request method starts with this line:

var _self = this;

Within the Promise definition we need to refer to the two class properties (timeout and result). The problem is that if you use this.timeout, the this will refer to the Promise that it is encapsulated in. So the this that refers to the mock class has to be assigned to a different property.

return new Promise( function (resolve, reject) {
  setTimeout( function() {
    resolve( _self.result )
  }, _self.timeout );
});

The request method returns a new Promise.

The promise will resolve to the value of the mock server result property.

By wrapping the call in setTimeout we can control how long it takes for the Promise to resolve. The time is controlled by the mock server timeout property.

Step 4. Write some async tests

Replace the code in test/smoke-test.js with the code below:

"use strict";

// require assert
var assert = require('assert');

// require the factory module
const mockFactory = require('../src');

describe('smoke test', function() {
  context('createMockServer', function() {
    // factory method
    it('should return an object that is not null', function(done) {
      var server = mockFactory.createMockServer();
      assert.ok(server, 'server should not be null');
      done();
    });
    // mock server call
    it('should return default result', async function() {
      var server = mockFactory.createMockServer();
      const TEST_RESULT = server.result;
      const result = await server.request();
      assert.deepEqual(result, TEST_RESULT, 
        'results not what expected');
    });
  });
});

For async testing the focus of this article is the last test.

  • The test code is wrapped in an async function

When a function is marked as async in JavaScript, that means that it will be returning a Promise.

  • The factory method creates a new mock server (server)
  • For testing, the default result is saved to TEST_RESULT
  • The server.request() call is made using an await
  • Finally the assert.deepEqual method is used to verify that the server.request() call returned the default result
  • Notice that there is no done call

Step 5. Run the tests

npm test

Review the results:

smoke test
  createMockServer
    ✓ should return an object that is not null
    ✓ should return default result (100ms)

2 passing (109ms)

The second test includes the time it took the test to run (100ms). The default timeout value for the mock server is 100. Sometimes a test will run a little longer if it is doing more.

Step 6. Add a timing test

Having mocha log the time something took is useful. But sometimes you will want to automate a test for how long a procedure within your test took.

In this step I’m going to show you how to save the time before and after an async call is made. Then calculate and test the difference.

Add the test below:

it('should return after timeout', async function() {
  var server = mockFactory.createMockServer();
  const TEST_RESULT = server.result;
  const TEST_TIMEOUT = 1500;
  server.timeout = TEST_TIMEOUT;
  const start = new Date();
  const result = await server.request();
  const finish = new Date();
  const diff = finish - start;
  assert.ok( diff >= TEST_TIMEOUT, 'test returned before timeout' );
  assert.deepEqual(result, TEST_RESULT, 'results not what expected');
});

This test does the following:

  • Uses async because await will be called within the test function
  • Creates a new mock server (server) using the factory method (createMockServer)
  • Saves the expected response into TEST_RESULT for verifying later
  • Defines a new TEST_TIMEOUT constant (in milliseconds)
  • Overrides the default server.timeout with TEST_TIMEOUT
  • Saves the current date and time into start
  • Assigns the server.request to result
  • The await call will cause JavaScript to wait until the Promise returned by the request method either rejects or resolves
  • When the Promise returns, finish is assigned the current date and time
  • The diff value is assigned finish-start in milliseconds
  • The difference should be greater than or equal to the timeout
  • The returned result should equal what is defaut mock server result

Step 7. Run the updated tests

npm test

Review the results:

smoke test
  createMockServer
    ✓ should return an object that is not null
    ✓ should return default result (101ms)
    ✓ should return after timeout (1501ms)

3 passing (2s)

Notice that the new test took 1500ms or more.

Step 8. Testing with large timeouts

If a test takes more than 2 seconds (2000 milliseconds), by default mocha will time out.

Update the last test by changing the TEST_TIMEOUT to 2500 and save the file.

const TEST_TIMEOUT = 2500;

Run the tests again:

npm test

You will see a response like this:

  smoke test
    createMockServer
      ✓ should return an object that is not null
      ✓ should return default result (101ms)
      1) should return after timeout

  2 passing (2s)
  1 failing

  1) smoke test
       createMockServer
         should return after timeout:
     Error: Timeout of 2000ms exceeded. For async tests and hooks, 
     ensure "done()" is called; if returning a Promise, 
     ensure it resolves. (/test/smoke-test.js)
      at listOnTimeout (internal/timers.js:549:17)
      at processTimers (internal/timers.js:492:7)

This is a problem when testing Web apps. Sometimes a server can take more than 2 seconds to respond.

You can fix the problem by setting the MochaJS timeout option either as a flag or as an option.

The quickest way to do that is to update the npm test script in package.json with a new flag.

Add a flag to make the test timeout 5000 milliseconds (5 seconds).

 "test": "mocha --timeout 5000"

Run the tests again and they should all pass because nothing timed out.

Step 9. Using mocha timeout

You can also override the timeout default and flag settings by setting the timeout for a test individually.

Add these two tests:

it('default timeout', function(done) {
  assert.ok(true);
  setTimeout(done, 5100);
});
it('override timeout', function(done) {
  this.timeout(6000);
  assert.ok(true);
  setTimeout(done, 5100);
});

The first one will take 5100ms — so it will go beyond the flag setting of 5000ms and fail with a timeout.

The second one overrides the flag timeout by setting the timeout to 6000ms and will pass.

This is useful when you only want to allow one specific test to take a long time.

If you run the tests again, the output will look like this:

> ./node_modules/mocha/bin/mocha --timeout 5000

  smoke test
    createMockServer
      ✓ should return an object that is not null
      ✓ should return default result (106ms)
      ✓ should return after timeout (2502ms)
      1) default timeout
      ✓ override timeout (5106ms)

  4 passing (13s)
  1 failing

  1) smoke test
       createMockServer
         default timeout:
     Error: Timeout of 5000ms exceeded. For async tests and hooks, 
     ensure "done()" is called; if returning a Promise, ensure it 
     resolves. 

The lengthy test that didn’t override the timeout failed, the other one passed.

Troubleshooting

If you run into weirdness when testing make sure that you aren’t using arrow functions. Especially when using this.timeout. MochaJS discourages using arrow function when defining tests.

Conclusion

In this article you learned how to do the following:

  • Build a mock Web server to simulate real server delays
  • Test requests asynchronously
  • Override the MochaJS default timeout setting

Related Articles

Here are some links to related articles that I’ve written:

  • How to Setup Mocha for Software Testing (MochaJS)
  • How to use Assert in MochaJS

References

  • Async/await [1]
  • MochaJS arrow functions [2]

Answer by Harris Ramos

JavaScript API for running tests,In serial mode, run after all tests end, once only,optionally run tests that match a regexp,In serial mode (Mocha’s default), before all tests begin, once only

Install with npm globally:

$ npm install --global mocha

or as a development dependency for your project:

$ npm install --save-dev mocha

# Getting Started

$ npm install mocha
$ mkdir test
$ $EDITOR test/test.js # or open with your favorite editor

In your editor:

var assert = require('assert');
describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      assert.equal([1, 2, 3].indexOf(4), -1);
    });
  });
});

Back in the terminal:

$ ./node_modules/mocha/bin/mocha

  Array
    #indexOf()
      ✓ should return -1 when the value is not present


  1 passing (9ms)

Answer by Cayden Ballard

Mocha supports async functions out of the box, no plugins or configuration needed. You can pass an async function to it(), and Mocha will handle any errors that occur.,Suppose you have an asynchronous function that makes an HTTP request using Axios.,In other words, if you return a promise or promise from your it() function, Mocha will handle it for you.,If you see this error, either you need to increase your Mocha test timeout or there’s some bug in your code that’s preventing done() from getting called.

Suppose you have an asynchronous function that makes an HTTP request using Axios.

const axios = require('axios');

function get(url, cb) {
  return axios.get(url);
}

Mocha supports async functions out of the box, no plugins or configuration needed. You can pass an async function to it(), and Mocha will handle any errors that occur.

describe('get()', function() {
  it('works', async function() {
    const res = await get('http://httpbin.org/get?answer=42');
    assert.equal(res.data.args.answer, 42);
  });
});

In other words, if you return a promise or promise from your it() function, Mocha will handle it for you.

describe('get()', function() {
  it('works', function() {
    return get('http://httpbin.org/get?answer=42').
      then(res => assert.equal(res.data.args.answer, 42));
  });
});

Mocha inspects the function you pass to it(). If that function takes a parameter, Mocha assumes that parameter is a done() callback that you will call to indicate your test is done. Here’s how you would test the get() function using Mocha’s done() callback.

describe('get()', function() {
  it('works', function(done) {
    get('http://httpbin.org/get?answer=42').
      then(res => {
        assert.equal(res.data.args.answer, 42);
        // `done()` with no parameters means the test succeeded
        done();
      }).
      // If you pass a parameter to `done()`, Mocha considers that an error
      catch(err => done(err));
  });
});

Make sure you call done()! If you don’t call done(), your Mocha test will time out. You’ll see the below error:

Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called

Answer by Kira Branch

You don’t need done nor async for your it.,Since async functions always implicitly return a Promise you can just do:,

What is the earliest my warlock can gain the nondetection spell, preferably without multiclassing?

,Connect and share knowledge within a single location that is structured and easy to search.

Since async functions always implicitly return a Promise you can just do:

async function getFoo() {
  return 'foo'
}

describe('#getFoo', () => {
  it('resolves with foo', () => {
    return getFoo().then(result => {
      assert.equal(result, 'foo')
    })
  })
})

If you still insist on using async/await:

async function getFoo() {
  return 'foo'
}

describe('#getFoo', () => {
  it('returns foo', async () => {
    const result = await getFoo()
    assert.equal(result, 'foo')
  })
})

Answer by Noor Acevedo

To indicate that a test is Asynchronous in Mocha, you simply pass a callback as the first argument to the it() method:,It was at this point that I hit a bit of a hiccup. So far all of the code written was synchronous. The Feedparser interface was asynchronous. I would need to rework the RSS-Reader tests, and the API, to handle this.,Even when you’re a JavaScript guru, asynchronous code is painful to test. Don’t jump through hoops to use callbacks when returning a value suffices. As an example, the code for tweeter.js does not use a single callback.,sinon.mock() continues to mock the readFeed() method. Now it executes a callback with a list of news articles rather than returning the array immediately.

To indicate that a test is Asynchronous in Mocha, you simply pass a callback as the first argument to the it() method:

it('should be asynchronous', function(done) {
  setTimeout(function() {
    done();
  }, 500);
});


Answer by Israel Bauer

Let’s put all this together to test some asynchronous code using async/await syntax. Here we have an asynchronous add() function which adds two numbers. We combine Mocha with Chai’s expect style while using ES7 async/await syntax.,Mocha is a JavaScript test framework running on Node.js and in the browser. It can run both asynchronous and synchronous code serially. Test cases are created using describe() and it() methods, the former is used to provide a structure by allowing to put various tests cases in logical groups while the latter is where the tests are written.,Finally Mocha, prints uncaught exceptions alongside the test cases in which they were thrown, making it easy to identify exactly what failed and why.,Next, we need to install both mocha and chai as development dependencies

Here’s an example of BDD style using should:

chai.should();

foo.should.be.a('string');
foo.should.equal('bar');
foo.should.have.lengthOf(3);
tea.should.have.property('flavors').with.lengthOf(3);

And here’s an example of TDD style using expect:

const expect = chai.expect;

expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.lengthOf(3);
expect(tea).to.have.property('flavors').with.lengthOf(3);

Let’s put all this together to test some asynchronous code using async/await syntax. Here we have an asynchronous add() function which adds two numbers. We combine Mocha with Chai’s expect style while using ES7 async/await syntax.

const expect = require('chai').expect;

async function add(a, b) {
  return Promise.resolve(a + b);
}

describe('#add()', () => {
  it('2 + 2 is 4', async () => {
    const p = await add(2, 2)
    expect(p).to.equal(4);
  });

  it('3 + 3 is 6', async () => {
    const p = await add(3, 3)
    expect(p).to.equal(6);
  });
});

In order to run let’s create a new Node.js project

mkdir async-await-mocha-chai-example
cd async-await-mocha-chai-example
yarn init -y

Next, we need to install both mocha and chai as development dependencies

yarn add mocha chai --dev

Finally, let’s put our test under test/add.test.js and run it.

yarn run mocha
yarn run mocha
yarn run v0.22.0

  #add()
    ✓ 2 + 2 is 4
    ✓ 3 + 3 is 6

  4 passing (199ms)

✨  Done in 0.99s.

For convenience, we can add a test command in scripts section of package.json

"scripts": {
  "test": "mocha --reporter list"
}

Mocha also provides hook methods which are used to take care of external resources (setup and teardown) either before or after all tests using before() and after() methods, or before and after each particular test with beforeEach() and afterEach(). Here’s an example showing how to test database persistance. The database connection is established once before all tests while the database is initialized from scratch before each test so they start from the same initial state.

const expect = require('chai').expect;
const Sequelize = require('sequelize');

describe('users', () => {
  let database;
  let User;

  before(async () => {
    database = new Sequelize('postgresql://localhost/app_test', { logging: false });
    User = database.define('user', {
      username: Sequelize.STRING,
      birthday: Sequelize.DATE
    });
  })

  beforeEach(async () => {
    await User.sync();
    await User.create({
      username: 'zaiste',
      birthday: new Date(1988, 1, 21)
    });
  })

  afterEach(async () => {
    await User.drop();
  })

  describe('#find()', () => {
    it('should find a user', async () => {
      const user = await User.findOne({ where: { username: 'zaiste' }})
      expect(user).to.be.a('object');
      expect(user).to.have.property('username');
      expect(user).to.have.property('birthday');
      expect(user.username).to.equal('zaiste');
    });
  });
});

Answer by Nixon Chambers

If you don’t want to use the done() callback, you can return a Promise. This is useful when the APIs that you are testing returns promises rather than callbacks:, An alternative approach is to use the done() callback directly ( which handles an error argument, in the case where it exists):, Generally, when this module throws an Error, it works! This implies that you can use libraries such as:,In versions of Mocha greater than v3.0.0, returning a Promise and calling done() results in an exception, as it is generally a mistake:

Continuing from our previous tutorial, recall that we gave you had an example which utilized Node.js built-in assert module:

var assert = require('assert');
describe('Array', function() {
  describe('#indexOf()', function() {
    it('has to return -1 when the value is not present', function() {
      assert.equal([1, 2, 3].indexOf(4), -1);
    });
  });
});

This is the second feature we will discuss, when it comes to testing asynchronous code, Mocha makes it so simple. All you need to do is to invoke the callback when your test complete. When you add a callback (which is usually named done) to it(), Mocha knows that it should wait for this function to be called to complete the test. This callback will accept both an Error instance or subclass thereof) or a falsy value; anything else causes a failed test.

describe('User', function() {
  describe('#save()', function() {
    it('has to save without error', function(done) {
      var user = new User('Luna');
      user.save(function(err) {
        if (err) done(err);
        else done();
      });
    });
  });
});

An alternative approach is to use the done() callback directly ( which handles an error argument, in the case where it exists):

describe('User', function() {
  describe('#save()', function() {
    it('has to save without error', function(done) {
      var user = new User('Luna');
      user.save(done);
    });
  });
});

If you don’t want to use the done() callback, you can return a Promise. This is useful when the APIs that you are testing returns promises rather than callbacks:

beforeEach(function() {
  return db.clear().then(function() {
    return db.save([tobi, loki, jane]);
  });
});
beforeEach(function() {
  return db.clear().then(function() {
    return db.save([tobi, loki, jane]);
  });
});
describe('#find()', function() {
  it('will respond with matching records', function() {
    return db.find({type: 'User'}).should.eventually.have.length(3);
  });
});

In versions of Mocha greater than v3.0.0, returning a Promise and calling done() results in an exception, as it is generally a mistake:

const assert = require('assert');

// antipattern
it('has to complete this test', function(done) {
  return new Promise(function(resolve) {
    assert.ok(true);
    resolve();
  }).then(done);
});

In the case where your JS environment supports async/await, you can as well write asynchronous tests like this:

beforeEach(async function() {
  await db.clear();
  await db.save([tobi, loki, jane]);
});

describe('#find()', function() {
  it('will respond with matching records', async function() {
    const users = await db.find({type: 'User'});
    users.should.have.length(3);
  });
});

Answer by Elyse Craig

https://stackoverflow.com/questions/63062843/how-to-test-process-on-using-mocha,There are myriad test frameworks available, including Jest, Jasmine, QUnit, Karma, Cypress, and several others. One of the most popular test frameworks for JavaScript is Mocha.js.,To get the list of available options you can apply to mocha, run the following command.,Writing a test suite with Mocha.js

/* package.json */

{
  "scripts": {
    "test": "mocha"
  }
}

Answer by Jaxx Lawson

// async/await
it('responds with matching records', async function() {
  const users = await db.find({ type: 'User' });
  users.should.have.length(3);
});

// promise.then()
it('should save without error', function(done) {
  var user = new User('Luna');
  user.save(function(err) {
    if (err) done(err);
    else done();
  });
});

Answer by August Dominguez

Mocha has built-in support for async tests that return a Promise. However, run into troubles with async and promises in the hook functions like before/beforEach/etc…. So if you keep reading you’ll see a helper function that I’ve not had any issues with (besides it’s a bit more work…).,all we have to do to turn it into an asynchronous test is to add a callback function as the first parameter in the mocha test function (I like to call it done) like this,The big changes from the above Promise style test and the transformed async test below are:,NOTE: You’re mileage may vary with the async/await and mocha tests with promises. I tried playing around with async in mocha hooks like before/beforeEach but ran into some troubles.

If you look at a normal synchronous test:

it("should work", function(){
    console.log("Synchronous test");
});

all we have to do to turn it into an asynchronous test is to add a callback function as the first parameter in the mocha test function (I like to call it done) like this

it("should work", function(done){
    console.log("Synchronous test");
});

This first async example test we show is invalid because the done callback is never called. Here’s another example using setTimeout to simulate proper asynchronicity. This will show up in Mocha as a timeout error because we never signal back to mocha by calling our done method.

it("where we forget the done() callback!", function(done){
    setTimeout(function() {
        console.log("Test");
    }, 200);
});

When we call the done method it tells Mocha the asynchronous work/test is complete.

it("Using setTimeout to simulate asynchronous code!", function(done){
    setTimeout(function() {
        done();
    }, 200);
});

With asynchronous tests, the way we tell Mocha the test failed is by passing an Error or string to the done(...) callback

it("Using setTimeout to simulate asynchronous code!", function(done){
    setTimeout(function() {
        done(new Error("This is a sample failing async test"));
    }, 200);
});

If you were to run the below test it would fail with a timeout error.

it("Using a Promise that resolves successfully!", function(done) {
    var testPromise = new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve("Hello!");
        }, 200);
    });

    testPromise.then(function(result) {
        expect(result).to.equal("Hello World!");
        done();
    }, done);
});

If you were to open up your developer tools you may notice an error printed to the console:

    Uncaught (in promise) i {message: "expected 'Hello!' to equal 'Hello World!'", showDiff: true, actual: "Hello!", expected: "Hello World!"}

We can update the above test with a try/catch around our expectations that could throw exceptions so that we can report any errors to Mocha if they happened.

it("Using a Promise that resolves successfully with wrong expectation!", function(done) {
    var testPromise = new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve("Hello World!");
        }, 200);
    });

    testPromise.then(function(result){
        try {
            expect(result).to.equal("Hello!");
            done();
        } catch(err) {
            done(err);
        }
    }, done);
});

Here’s an example of returning a Promise that correctly fails the test with the readable error message from Chaijs.

it("Using a Promise that resolves successfully with wrong expectation!", function() {
    var testPromise = new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve("Hello World!");
        }, 200);
    });

    return testPromise.then(function(result){
        expect(result).to.equal("Hello!");
    });
});

If we apply the 5 notes listed above, we see that we can greatly improve the test readability.

it("Using a Promise with async/await that resolves successfully with wrong expectation!", async function() {
    var testPromise = new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve("Hello World!");
        }, 200);
    });

    var result = await testPromise;

    expect(result).to.equal("Hello!");
});

Below shows the (failing) but alternative way (not using a return Promsie) but using the done callback instead.

it("Using a Promise with async/await that resolves successfully with wrong expectation!", async function(done) {
    var testPromise = new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve("Hello World!");
        }, 200);
    });

    try {
        var result = await testPromise;

        expect(result).to.equal("Hello!");

        done();
    } catch(err) {
        done(err);
    }
});

another example below with the async/await and try/catch

it("Using an async method with async/await!", async function(done) {
    try {
        var result = await somethingAsync();

        expect(result).to.equal(something);

        done();
    } catch(err) {
        done(err);
    }
});

This simple little guy takes an async function which looks like async () => {...}. It then returns a higher order function which is also asynchronous but has wrapped your test function in a try/catch and also takes care of calling the mocha done in the proper place (either after your test is asynchronously completed, or errors out).

var mochaAsync = (fn) => {
    return async (done) => {
        try {
            await fn();
            done();
        } catch (err) {
            done(err);
        }
    };
};

You can use it like this:

it("Sample async/await mocha test using wrapper", mochaAsync(async () => {
    var x = await someAsyncMethodToTest();
    expect(x).to.equal(true);
}));

It can also be used with the mocha before, beforeEach, after, afterEach setup/teardown methods.

beforeEach(mochaAsync(async () => {
    await someLongSetupCode();
}));

Понравилась статья? Поделить с друзьями:
  • Error timed out while waiting for target halted
  • Error timed out while waiting for handshake
  • Error timed out waiting for any update progress to be made
  • Error timed out recheck in 1 min
  • Error time was not declared in this scope