开玩笑地模拟 fs 与配置模块发生冲突
Mocking fs with jest clashes with config module
我正在尝试对以下文件进行单元测试:
import { readFileSync } from 'fs';
import logger from './logger.utils';
export const readFile = async (targetDir: string, fileName: string): Promise<string> => {
logger.info(`start reading from ${targetDir}/${fileName}`);
const data = readFileSync(`${targetDir}/${fileName}`, {encoding: 'utf8', flag: 'r'});
return data;
};
jest测试文件
import { mocked } from 'ts-jest/utils';
import fs from 'fs';
jest.mock('fs');
import * as fsUtils from '../../src/utils/fs.utils';
let readFileSyncMock: jest.SpyInstance;
describe('fs.utils', () => {
describe('readFile', () => {
afterEach(() => {
readFileSyncMock.mockReset();
});
afterAll(() => {
readFileSyncMock.mockRestore();
});
it('should create a new log directory if one doesn\'t already exist', async () => {
mocked(fs.readFileSync as jest.Mock).mockImplementation(() => { ('some string') });
const fileData = await fsUtils.readFile('target_directory', 'file_name');
expect(fileData).toEqual('some string');
});
});
});
当我 运行 测试时出现以下错误:
Config file /Users/dfaizulaev/Documents/projectname/config/runtime.json cannot be read. Error code is: undefined. Error message is: Cannot read property 'replace' of undefined
1 | import loggingContext from './loggingContext';
> 2 | import config from 'config';
| ^
3 | import os from 'os';
4 | import constants from '../../config/constants';
5 |
at Config.Object.<anonymous>.util.parseFile (node_modules/config/lib/config.js:821:13)
at Config.Object.<anonymous>.util.loadFileConfigs (node_modules/config/lib/config.js:697:26)
at new Config (node_modules/config/lib/config.js:116:27)
at Object.<anonymous> (node_modules/config/lib/config.js:1492:31)
at Object.<anonymous> (src/utils/logger.utils.ts:3:1)
错误来自于上述fs模块文件导入的logger文件。
logger.utils
文件
import loggingContext from './loggingContext';
import config from 'config';
import os from 'os';
import constants from '../../config/constants';
const LOG_LEVEL: string = config.get(constants.LOG_LEVEL);
.... more logic ....
我认为错误的原因是我没有正确模拟 fs
模块,但我尝试了各种方法并不断收到此错误。
请指教
问题是因为我正在模拟 config
包中使用的整个 fs
模块。
删除了 jest.mock('fs');
并分别模拟了这些方法。
例如:
import fs, { Stats, promises } from 'fs';
import * as fsUtils from '../../src/utils/fs.utils';
describe('fs.utils', () => {
afterEach(() => {
jest.resetAllMocks();
});
describe('statSync', () => {
it('Should successfully call statSync', () => {
jest.spyOn(fs, 'statSync').mockReturnValue({ size: 1000 } as Stats);
const result = fsUtils.getFileSize('file path');
expect(result).toEqual(1000);
});
});
describe('writeFile', () => {
it('Should successfully call writeFile', async () => {
jest.spyOn(promises, 'writeFile').mockResolvedValue();
await fsUtils.writeFile('file path', 'data');
});
});
describe('writeFile', () => {
it('Should successfully call writeFile', async () => {
jest.spyOn(promises, 'readFile').mockResolvedValue('some file content');
const result = await fsUtils.readFile('filePath', 'fileName');
expect(result).toEqual('some file content');
});
});
});
我正在尝试对以下文件进行单元测试:
import { readFileSync } from 'fs';
import logger from './logger.utils';
export const readFile = async (targetDir: string, fileName: string): Promise<string> => {
logger.info(`start reading from ${targetDir}/${fileName}`);
const data = readFileSync(`${targetDir}/${fileName}`, {encoding: 'utf8', flag: 'r'});
return data;
};
jest测试文件
import { mocked } from 'ts-jest/utils';
import fs from 'fs';
jest.mock('fs');
import * as fsUtils from '../../src/utils/fs.utils';
let readFileSyncMock: jest.SpyInstance;
describe('fs.utils', () => {
describe('readFile', () => {
afterEach(() => {
readFileSyncMock.mockReset();
});
afterAll(() => {
readFileSyncMock.mockRestore();
});
it('should create a new log directory if one doesn\'t already exist', async () => {
mocked(fs.readFileSync as jest.Mock).mockImplementation(() => { ('some string') });
const fileData = await fsUtils.readFile('target_directory', 'file_name');
expect(fileData).toEqual('some string');
});
});
});
当我 运行 测试时出现以下错误:
Config file /Users/dfaizulaev/Documents/projectname/config/runtime.json cannot be read. Error code is: undefined. Error message is: Cannot read property 'replace' of undefined
1 | import loggingContext from './loggingContext';
> 2 | import config from 'config';
| ^
3 | import os from 'os';
4 | import constants from '../../config/constants';
5 |
at Config.Object.<anonymous>.util.parseFile (node_modules/config/lib/config.js:821:13)
at Config.Object.<anonymous>.util.loadFileConfigs (node_modules/config/lib/config.js:697:26)
at new Config (node_modules/config/lib/config.js:116:27)
at Object.<anonymous> (node_modules/config/lib/config.js:1492:31)
at Object.<anonymous> (src/utils/logger.utils.ts:3:1)
错误来自于上述fs模块文件导入的logger文件。
logger.utils
文件
import loggingContext from './loggingContext';
import config from 'config';
import os from 'os';
import constants from '../../config/constants';
const LOG_LEVEL: string = config.get(constants.LOG_LEVEL);
.... more logic ....
我认为错误的原因是我没有正确模拟 fs
模块,但我尝试了各种方法并不断收到此错误。
请指教
问题是因为我正在模拟 config
包中使用的整个 fs
模块。
删除了 jest.mock('fs');
并分别模拟了这些方法。
例如:
import fs, { Stats, promises } from 'fs';
import * as fsUtils from '../../src/utils/fs.utils';
describe('fs.utils', () => {
afterEach(() => {
jest.resetAllMocks();
});
describe('statSync', () => {
it('Should successfully call statSync', () => {
jest.spyOn(fs, 'statSync').mockReturnValue({ size: 1000 } as Stats);
const result = fsUtils.getFileSize('file path');
expect(result).toEqual(1000);
});
});
describe('writeFile', () => {
it('Should successfully call writeFile', async () => {
jest.spyOn(promises, 'writeFile').mockResolvedValue();
await fsUtils.writeFile('file path', 'data');
});
});
describe('writeFile', () => {
it('Should successfully call writeFile', async () => {
jest.spyOn(promises, 'readFile').mockResolvedValue('some file content');
const result = await fsUtils.readFile('filePath', 'fileName');
expect(result).toEqual('some file content');
});
});
});