I am attempting to use Jest for my Node Js Test (specifically AWS's Lambda) but I am having difficulty mocking async await functionality.
I am using babel-jest and jest-cli. Below are my modules. I am getting to the first console.log, but the second console.log returns undefined and my test crash.
Any ideas on how to implement this?
Below is my module:
import {callAnotherFunction} from '../../../utils';
export const handler = async (event, context, callback) => {
const {emailAddress, emailType} = event.body;
console.log("**** GETTING HERE = 1")
const sub = await callAnotherFunction(emailAddress, emailType);
console.log("**** Not GETTING HERE = 2", sub) // **returns undefined**
// do something else here
callback(null, {success: true, returnValue: sub})
}
My Test
import testData from '../data.js';
import { handler } from '../src/index.js';
jest.mock('../../../utils');
beforeAll(() => {
const callAnotherLambdaFunction= jest.fn().mockReturnValue(Promise.resolve({success: true}));
});
describe('>>> SEND EMAIL LAMBDA', () => {
test('returns a good value', done => {
function callback(dataTest123) {
expect(dataTest123).toBe({success: true, returnValue: sub);
done();
}
handler(testData, null, callback);
},10000);
})
Async functions are available natively in Node and are denoted by the async keyword in their declaration. They always return a promise, even if you don't explicitly write them to do so. Also, the await keyword is only available inside async functions at the moment – it cannot be used in the global scope.
To enable async/await in your project, install @babel/preset-env and enable the feature in your babel. config. js file.
Jest typically expects to execute the tests' functions synchronously. If we do an asynchronous operation, but we don't let Jest know that it should wait for the test to end, it will give a false positive.
In this way, an async function without an await expression will run synchronously. If there is an await expression inside the function body, however, the async function will always complete asynchronously. Code after each await expression can be thought of as existing in a .then callback.
You should be careful about somethings below:
Import your utils
as a module then mock callAnotherLambdaFunction
function
Mock return value of callAnotherLambdaFunction
with Resolve
and Reject
case
https://jestjs.io/docs/en/mock-function-api.html#mockfnmockresolvedvaluevalue
This is my example:
import testData from '../data.js';
import { handler } from '../src/index.js';
import * as Utils from '../../../utils'
jest.mock('../../../utils');
beforeAll(() => {
Utils.callAnotherLambdaFunction = jest.fn().mockResolvedValue('test');
});
describe('>>> SEND EMAIL LAMBDA', () => {
it('should return a good value', async () => {
const callback = jest.fn()
await handler(testData, null, callback);
expect(callback).toBeCalledWith(null, {success: true, returnValue: 'test'})
});
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With