I'm trying to test a file which uses zlib
which is wrapped in promisify
but when the test reaches the line in the code which uses zlib
I get a jest timeout error.
: Timeout - Async callback was not invoked within the 30000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 30000 ms timeout specified by jest.setTimeout.Error:
Module file:
import zlib from 'zlib';
import util from 'util';
const zlibGunzip = util.promisify(zlib.gunzip);
async function unzipObjectContent(objectBody): Promise<string> {
const buff = objectBody as Buffer;
try {
const data = await zlibGunzip(buff);
const utf8String = data.toString('utf8');
const parsedJson = JSON.parse(utf8String);
return JSON.stringify(parsedJson);
} catch (error) {
logger.error(`unzipObjectContent -> failed to unzip file ${error}`);
throw error;
}
}
Test File
jest.mock('zlib');
import zlib from 'zlib';
let gunzipMock: jest.SpyInstance;
gunzipMock = jest.spyOn(zlib, 'gunzip');
gunzipMock.mockResolvedValue(JSON.stringify(problemZipContent));
When I debug the test, I see that it reaches the call to await zlibGunzip(buff);
but then an error is thrown. It does not reaches the catch block either.
Please advise on how can I test this. Thank you
Mock the zlib.gunzip()
method and its implementation, since the second argument of this method is a Node.js error-first callback, you need to call the callback
function manually in your test. So that the promise returned from util.promisify(zlib.gunzip)
will be resolved.
E.g.
index.ts
:
import zlib from 'zlib';
import util from 'util';
const zlibGunzip = util.promisify(zlib.gunzip);
export async function unzipObjectContent(objectBody): Promise<string> {
const buff = objectBody as Buffer;
try {
const data = await zlibGunzip(buff);
const utf8String = data.toString('utf8');
const parsedJson = JSON.parse(utf8String);
return JSON.stringify(parsedJson);
} catch (error) {
console.error(`unzipObjectContent -> failed to unzip file ${error}`);
throw error;
}
}
index.test.ts
:
import zlib from 'zlib';
import { unzipObjectContent } from './';
import { mocked } from 'ts-jest/utils';
jest.mock('zlib');
const mzlib = mocked(zlib);
describe('67475685', () => {
afterAll(() => {
jest.resetAllMocks();
});
it('should pass', async () => {
const problemZipContent = Buffer.from(JSON.stringify({ name: 'teresa teng' }));
mzlib.gunzip.mockImplementationOnce((buffer, callback: any) => {
callback(null, problemZipContent);
});
const actual = await unzipObjectContent(problemZipContent);
expect(actual).toEqual('{"name":"teresa teng"}');
expect(mzlib.gunzip).toBeCalledTimes(1);
});
});
test result:
PASS examples/67475685/index.test.ts (7.156 s)
67475685
✓ should pass (4 ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 83.33 | 100 | 100 | 83.33 |
index.ts | 83.33 | 100 | 100 | 83.33 | 16-17
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 7.656 s, estimated 8 s