您可以使用jest.mock(moduleName, factory, options) 模拟ftp 包及其Client 类。
由于您的代码是在模块范围内定义的,因此您的代码将在导入模块时执行。我们需要在导入模块之前创建模拟对象。
另外,我在error事件处理程序中使用console.log来代表你的具体代码实现。
例如
index.ts:
import Client from 'ftp';
const c = new Client();
c.on('ready', () => {
c.list((err, list) => {
if (err) throw err;
c.end();
});
});
c.on('error', () => {
console.log('handle error');
});
c.connect();
index.test.ts:
const mc = {
on: jest.fn(),
list: jest.fn(),
end: jest.fn(),
connect: jest.fn(),
};
jest.mock('ftp', () => {
return jest.fn(() => mc);
});
describe('67951757', () => {
beforeEach(() => {
jest.resetModules();
});
afterAll(() => {
jest.resetAllMocks();
});
afterEach(() => {
jest.clearAllMocks();
});
it('should handle ready', async () => {
mc.on.mockImplementation(function (event, handler) {
if (event === 'ready') {
handler();
}
return mc;
});
mc.list.mockImplementation((callback) => {
callback(null as any, []);
});
await import('./');
expect(mc.on).toBeCalledWith('ready', expect.any(Function));
expect(mc.on).toBeCalledWith('error', expect.any(Function));
expect(mc.connect).toBeCalledTimes(1);
expect(mc.list).toBeCalledWith(expect.any(Function));
expect(mc.end).toBeCalledTimes(1);
});
it('should handle list error', async () => {
mc.on.mockImplementation(function (event, handler) {
if (event === 'ready') {
handler();
}
return mc;
});
mc.list.mockImplementation((callback) => {
callback(new Error('memory leak'));
});
await expect(() => import('./')).rejects.toThrow('memory leak');
expect(mc.on).toBeCalledWith('ready', expect.any(Function));
expect(mc.list).toBeCalledWith(expect.any(Function));
expect(mc.end).not.toBeCalled();
});
it('should handle error', async () => {
mc.on.mockImplementation(function (event, handler) {
if (event === 'error') {
handler();
}
return mc;
});
mc.list.mockImplementation((callback) => {
callback(null as any, []);
});
const logSpy = jest.spyOn(console, 'log');
await import('./');
expect(mc.on).toBeCalledWith('error', expect.any(Function));
expect(mc.list).not.toBeCalled();
expect(logSpy).toBeCalledWith('handle error');
logSpy.mockRestore();
});
});
测试结果:
PASS examples/67951757/index.test.ts (9.59 s)
67951757
✓ should handle ready (7869 ms)
✓ should handle list error (4 ms)
✓ should handle error (19 ms)
console.log
handle error
at console.<anonymous> (node_modules/jest-mock/build/index.js:845:25)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.ts | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 10.802 s