I have the following code of the NodeJS AWS Lambda function I would like to cover by unit tests with Jest:
index.js
const { getConfig } = require('./modules/config/configManager');
const BridgeDataProvider = require('./modules/storage/bridge/bridgeDataProvider');
const ClientProcessor = require('./modules/domain/clientProcessor');
const configPromise = getConfig();
exports.handler = async () => {
const config = await configPromise;
if (!config.enabled) {
return;
}
const bridgeDataProvider = new BridgeDataProvider(config.bridgeDynamoDbConfig);
const clientProcessor = new ClientProcessor(config);
const clients = await bridgeDataProvider.getActiveClients();
for (const client of clients) {
await clientProcessor.process(client);
}
};
And I’m trying to mock getConfig
async function for each test individually, but unfortunately it doesn’t work. await getConfig()
in index.js
always returns undefined
Here’s the testing code:
index.test.js
const { getConfig } = require('../modules/config/configManager');
const { handler } = require('../index');
const BridgeDataProvider = require('../modules/storage/bridge/bridgeDataProvider');
const ClientProcessor = require('../modules/domain/clientProcessor');
jest.mock('../modules/config/configManager', () => ({
getConfig: jest.fn(),
}));
jest.mock('../modules/storage/bridge/bridgeDataProvider');
jest.mock('../modules/domain/clientProcessor');
const defaultMocks = {
BridgeDataProvider: {
getActiveClients: jest.fn().mockImplementation(() => {
/** @type {Client[]} */
const clients = [
{
id: '1234abc',
clientcode: 'Amazon',
},
{
id: '5678def',
clientcode: 'Facebook',
},
];
return Promise.resolve(clients);
}),
},
};
/**
* @typedef {import('../modules/config/config.types').AppConfig} AppConfig
* @typedef {import('../modules/storage/bridge/models.types').Client} Client
*/
describe('handler', () => {
beforeEach(() => {
jest.resetModules()
.clearAllMocks();
setupDefaultMocks();
});
it('does not handle clients if function is not enabled', async () => {
getConfig.mockResolvedValue({enabled: false, bridgeDynamoDbConfig: {}}); // this is not working, await getConfig() returns undefined in index.js
await handler();
const processMethod = ClientProcessor.mock.instances[0].process;
expect(processMethod).toHaveBeenCalledTimes(0);
});
});
function setupDefaultMocks() {
getConfig.mockResolvedValue({enabled: true, bridgeDynamoDbConfig: {}}); // this is not working, await getConfig() returns undefined in index.js
BridgeDataProvider.mockImplementation(() => defaultMocks.BridgeDataProvider);
}
Test output:
FAIL test/index.test.js
● handler › does not handle clients if function is not enabled
TypeError: Cannot read properties of undefined (reading 'enabled')
10 |
11 | const config = await configPromise;
> 12 | if (!config.enabled) {
| ^
13 | return;
14 | }
15 |
at enabled (index.js:12:17)
at Object.<anonymous> (test/index.test.js:48:9)
If I put default implementation right inside jest.mock('../modules/config/configManager', ...)
statement, it will mock resolved value as expected. Why is the mocking in individual test not working and how to make it work?