Wednesday, October 25, 2017

how to resolve async await inside a unit test - javascript

Leave a Comment

I have a lambda for which I'd like to write unit tests for. I'm using async await but I'm getting issues with resolve promises. I'd like to test the different conditions, how can I write the test to resolve and stop seeing the timeouts?

Thanks in advance.

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

--- unit

describe('tests', function() {      describe('describe an error', () => {         it('should return a 500', (done) => {             handler('', {}, (err, response) => {                 expect(err.status).to.eq('failed')                 done()             })         })     })  }); 

-- handler

export const handler = async (event, context, callback) => {    return callback(null, status: 500 )  }) 

4 Answers

Answers 1

Try following:

describe('tests', function() {     describe('describe an error', () => {         it('should return a 500', (done) => {             await handler('', {}, (err, response) => {                 expect(err.status).to.eq('failed');             })             done();         })     }) }); 

or

describe('tests', function() {     describe('describe an error', () => {         it('should return a 500', async () => {             const error =                await handler('', {}, (err, response) => Promise.resolve(err))             expect(error.status).to.eq('failed');         })     }) }); 

Anyway, I think, you need to await your async handler...

Answers 2

You can increase the timeout of your test.

describe('tests', function() {      describe('describe an error', () => {         it('should return a 500', (done) => {             handler('', {}, (err, response) => {                 expect(err.status).to.eq('failed')                 done()             })         }).timeout(5000)     })  }); 

The timeout method accepts the time in ms. Default is 2000

Answers 3

Depending on the framework you're using there're multiple ways to handle async unit tests.

For example if you're using Jasmine:

1) You can use Spy to replace your async callback with a static function, that way it won't be asyncronous and you can mock the return data. This can be useful for unit testing where you don't need to test dynamic async operations (unlike with integration tests).

2) There is also real async support documentation that can be found here: Asynchronous Support

3) You should always use beforeEach() with async tests as that's where you define your done() function on describe level

Answers 4

Use Blue Tape. It is a thin wrapper around Tape, a simple, productive test framework recommended by Eric Elliott among others.

Blue Tape handles any tests that return promises automatically.

All methods using async/await return promises per the ECMAScript specification.

Here is what it looks like

import test from 'blue-tape';  test('`functionThatReturnsAPromise` must return a status of "failed"', async ({equals}) => {   const {result} = await functionThatReturnsAPromise();   equals(status, 'failed'); }); 

You can even write synchronous test this way if you simply include the async keyword.

Note how there is no use of done or end or any of the other boilerplate and noise associated with asynchronous testing in most frameworks.

I strongly recommend you give it a try.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment