I have a simple function that use the library jszip to zip some folders and files:
// app.ts
const runJszip = async (): Promise<void> => {
const zip = new Jszip();
zip.folder('folder')?.file('file.txt', 'just some text');
zip.file('file.txt', 'just some text');
await zip.generateAsync({ type: 'blob' });
};
I want to test it by spying the methods folder
and file
. I used for that the mocking partial strategy to handle the default export of this library:
// app.test.ts
import { runJszip } from './app';
const mockFile = jest.fn();
const mockFolder = jest.fn();
const mockJszip = jest.fn().mockImplementation(() => {
return {
folder: mockFolder,
file: mockFile,
};
});
jest.mock('jszip', () => {
return jest.fn().mockImplementation(() => ({
__esModule: true,
default: mockJszip,
}));
});
test('jszip', async () => {
await runJszip();
expect(mockFile).toHaveBeenCalledTimes(2);
expect(mockFolder).toHaveBeenCalledTimes(1);
});
Unfortunately, it seems that I can't properly mock the folder
method as you can see in the following error message:
Message:
zip.folder is not a function
4 | const zip = new Jszip();
5 |
> 6 | zip.folder('folder')?.file('file.txt', 'just some text');
So does someone have an idea how I could mock and spy on this method?
Have a look at the minimal reproducible example.
CodePudding user response:
I have it working as expected by making mockFolder
in @bln's response returning a mocked Jszip instance:
import { runJszip } from './app';
const mockFile = jest.fn();
let mockFolder: jest.Mock;
function mockJszip() {
mockFolder = mockFolder ?? jest.fn(mockJszip);
return {
folder: mockFolder,
file: mockFile,
generateAsync: jest.fn(),
};
}
jest.mock('jszip', () => {
return {
__esModule: true,
default: mockJszip,
};
});
test('jszip', async () => {
await runJszip();
expect(mockFile).toHaveBeenCalledTimes(2);
expect(mockFolder).toHaveBeenCalledTimes(1);
});
https://stackblitz.com/edit/webpack-5-react-starter-ofxcmy?file=src/app.test.ts
CodePudding user response:
import { runJszip } from './app';
const mockFile = jest.fn();
const mockFolder = jest.fn();
function mockJszip() {
return {
folder: mockFolder,
file: mockFile,
generateAsync: jest.fn(),
};
}
jest.mock('jszip', () => {
return {
__esModule: true,
default: mockJszip,
};
});
test('jszip', async () => {
await runJszip();
expect(mockFile).toHaveBeenCalledTimes(2);
expect(mockFolder).toHaveBeenCalledTimes(1);
});
For the ?.file()
chaining, maybe with some mockImplementation
around mockJszip