A.G.Progm.Enthusiast
A.G.Progm.Enthusiast

Reputation: 1010

How to test a asynchronous server code using mocha chai?

In my mocha-test suite, I want to test a functionality which makes a asynchronous call behind the scene. How can I wait until the asynchronous call has finished ?

For example, I make two back to back post calls. The first post call also makes an asynchronous call internally, until that asynchronous operation is complete the second post call won't pass.

I need either of below:

1) to put a delay between the two post calls so that to make sure the asynchronous part in the first post is complete.
2) to make the second post call repetitively until it passes.
3) or how to test out the asynchronous call through mocha-chai ?

Below is the example:

describe('Back to back post calls with asynchronous operation', ()=> {

            it('1st and 2nd post', (done) => {
                chai.request(server)
                .post('/thisis/1st_post')
                .send()
                .end((err, res) => {
                 expect(res.statusCode).to.equal(200);

                 /* HERE I Need A Delay or a way to call                   
               the below post call may be for 5 times */                       

                 chai.request(server)
                .post('/thisis/second_post')
                .send()
                .end((err, res) => {
                 expect(res.statusCode).to.equal(200);


                });

                done();
                });
            });         

        });

Is there a way to handle this ? Please help.

Thanks.

Upvotes: 1

Views: 750

Answers (1)

Alexandru Olaru
Alexandru Olaru

Reputation: 7112

In order to test an asynchronous function with mocha you have the following possibilities

use done only after the last callback in your sequence was executed

it('1st and 2nd post', (done) => {
  chai.request(server)
    .post('/thisis/1st_post')
    .send()
    .end((err, res) => {
      expect(res.statusCode).to.equal(200);

      /* HERE I Need A Delay or a way to call
    the below post call may be for 5 times */

      chai.request(server)
        .post('/thisis/second_post')
        .send()
        .end((err, res) => {
          expect(res.statusCode).to.equal(200);

          //call done only after the last callback was executed
          done();
        });
    });
});

use done callback with promises

describe('test', () => {
  it('should do something async', (done) => {
    firstAsyncCall
       .then(() => {
          secondAsyncCall()
            .then(() => {
              done() // call done when you finished your calls
            }
       })
  });
})

After a proper refactor you will get something like

describe('test', () => {
  it('should do something async', (done) => {
    firstAsyncCall()
      .then(secondAsyncCall())
      .then(() => {
        // do your assertions
        done()
      })
      .catch(done)
  })
})

use async await, much cleaner

describe('test', () => {
  it('should do something async', async () => {
    const first = await firstAsyncCall()
    const second = await secondAsyncCall()

    // do your assertion, no done needed
  });
})

An other moment to keep in mind is the --timeout argument when running mocha tests. By default mocha is waiting 2000 miliseconds, you should specify a larger amount when the server is responding slower.

mocha --timeout 10000

Upvotes: 2

Related Questions