我正在尝试模拟 fs 模块(fs.promises)中的 copyFile 和 stat 方法。但是没有调用模拟函数,而是通过测试用例调用原始函数。
测试函数代码为:
jest.doMock('fs', () => ({
promises: {
copyFile: (src = 'source', dest = 'destination') =>
jest.fn().mockImplementation(async () => {
console.log('Inside the mock function in copyFile, please get executed, got frustrated', src, dest);
return Promise.resolve(false);
}),
stat: () =>
jest.fn().mockImplementation(async () => {
console.log('Inside the mock function in stat method, please get executed, got frustrated');
return Promise.resolve(false); // Probably wrong datatype
}),
},
}));
describe('Testing implementation', () => {
const sample = new MainFunction()
test('Testing', async () => {
expect(sample.demo()).toEqual(Promise.resolve(true));
});
});
需要测试的实际代码:
import * as fs from 'fs';
export class MainFunction {
async demo(): Promise<any> {
const fileName = 'C:/Users/Desktop/testing-file-dir/';
const fileName1 = '/destination/'
let filefound = (await fs.promises.stat(fileName)).isFile();
await fs.promises.copyFile(fileName,fileName1);
console.log(filefound, 'inside actual code');
return Promise.resolve(true);
}
}
有人可以帮忙解决我哪里出错了吗?我曾想过使用 jest.mock 但它也给出了错误,所以我按照这个链接 https://github.com/facebook/jest/issues/2567 建议尝试 doMock。如果有人知道处理这个模拟函数的更好方法,那就太好了。
谢谢!
答案 0 :(得分:1)
您可以使用 jest.mock(moduleName, factory, options),并且您没有正确模拟方法链调用。您应该使用 mockFn.mockReturnThis() 将此上下文返回给调用者。
例如
index.ts
:
import * as fs from 'fs';
export class MainFunction {
async demo(): Promise<any> {
const fileName = 'C:/Users/Desktop/testing-file-dir/';
const fileName1 = '/destination/';
let filefound = (await fs.promises.stat(fileName)).isFile();
await fs.promises.copyFile(fileName, fileName1);
console.log(filefound, 'inside actual code');
return Promise.resolve(true);
}
}
index.test.ts
import { MainFunction } from './';
jest.mock('fs', () => ({
promises: {
copyFile: jest.fn().mockImplementation((src = 'source', dest = 'destination') => {
console.log('Inside the mock function in copyFile, please get executed, got frustrated', src, dest);
return Promise.resolve(false);
}),
stat: jest.fn().mockReturnThis(),
isFile: jest.fn().mockImplementation(() => {
console.log('Inside the mock function in stat method, please get executed, got frustrated');
return Promise.resolve(false);
}),
},
}));
describe('Testing implementation', () => {
const sample = new MainFunction();
test('Testing', async () => {
const actual = await sample.demo();
expect(actual).toBeTruthy();
});
});
测试结果:
PASS examples/66429093/index.test.ts
Testing implementation
✓ Testing (10 ms)
console.log
Inside the mock function in stat method, please get executed, got frustrated
at Object.<anonymous> (examples/66429093/index.test.ts:12:15)
console.log
Inside the mock function in copyFile, please get executed, got frustrated C:/Users/Desktop/testing-file-dir/ /destination/
at Object.<anonymous> (examples/66429093/index.test.ts:7:15)
console.log
Promise { false } inside actual code
at MainFunction.<anonymous> (examples/66429093/index.ts:9:13)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.12 s, estimated 4 s
答案 1 :(得分:0)
根据 slideshowp2 的解决方案,我必须进行此更改以避免出现此 https://github.com/facebook/jest/issues/2567 中所述的错误。
实际文件保持不变,而测试文件更改为:
jest.mock('fs', () => {
const originalModule = jest.requireActual('fs'); // so as to not override other functions apart from below mentioned one's
return Object.assign({ __esModule: true }, originalModule, {
promises: {
copyFile: jest.fn().mockImplementation((src, dest) => {
// src, dest are parameters passed in copyFile from src to destination
let source = 'some source'; // sample source file
if (source === src) {
return true;
} else {
throw Error;
}
}),
stat: jest.fn().mockReturnThis(),
isFile: jest
.fn()
.mockImplementationOnce(() => { // I had series of test so for first one I wanted false hence this part, else we can remove this and directly use .mockImplementation()
return false;
})
.mockImplementation(() => {
return true;
}),
},
});
});
describe('Testing implementation', () => {
const sample = new MainFunction();
test('Testing', async () => {
const actual = await sample.demo();
expect(actual).toBeTruthy();
});
});