我正在尝试使用Jest为使用fs/promises
的模块编写TypeScript单元测试。我试图模拟readdir
函数,但我遇到了一些问题,我模拟的函数没有按预期调用。
下面是我的测试设置的简化版本:
// Mock setup
jest.mock('fs/promises', () => ({
readdir: jest.fn(),
readFile: jest.fn(),
}));
// Relevant imports
import { calculateMetrics } from '../tradeEvaluator';
import * as fs from 'fs/promises';
// Test block
describe('calculateMetrics', () => {
const readdirMock = fs.readdir as jest.MockedFunction<typeof fs.readdir>;
const readFileMock = fs.readFile as jest.MockedFunction<typeof fs.readFile>;
beforeEach(() => {
readdirMock.mockResolvedValue([/*... mocked data ...*/]);
});
it('should skip invalid JSON files', async () => {
await calculateMetrics('./data');
expect(readdirMock).toHaveBeenCalledTimes(1);
// other assertions...
});
});
当我运行我的测试时,我得到一个错误,指示readdir
没有被调用,即使我的calculateMetrics
函数应该调用它。
我得到这个错误:
>>>> expect(jest.fn()).toHaveBeenCalledTimes(expected)
Expected number of calls: 1
Received number of calls: 0
是否有我可能遗漏的特定步骤或我需要确保使其工作的模拟和导入的顺序?
$ node --version
v20.5.0
$ tsc --version
Version 5.1.6
// tradeEvaluator.ts
import { promises as fs } from 'fs';
import { join } from 'path';
import { createLogger, format, transports } from 'winston';
const args = process.argv.slice(2);
let optionalTicker = null;
// If a ticker symbol is provided, capture it
if (args.length > 0) {
optionalTicker = args[0];
}
export const logger = createLogger({
level: 'info',
format: format.combine(
format.timestamp(),
format.printf(({ timestamp, level, message }) => {
return `${timestamp} [${level}]: ${message}`;
})
),
transports: [
new transports.File({ filename: 'application.log' })
// new transports.Console() // if you still want to see the log in the console
]
});
export async function calculateMetrics(directory: string, tickerSymbol: string | null = null): Promise<void> {
let files;
try {
files = await fs.readdir(directory);
} catch(e) {
console.error(`Error reading directory ${directory}:`, e);
return;
}
if (!files || !files.length) {
console.error(`No files found in directory ${directory}`);
return;
}
.
.
.
组态:
tsconfig.build.json
{
"compilerOptions": {
"target": "es2022",
"module": "commonjs",
"moduleResolution": "node",
"outDir": "./build",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "**/*.test.ts"]
}
{
"compilerOptions": {
"outDir": "./build",
"module": "commonjs",
"target": "es6",
"strict": true
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules/alphalytics-data/src/**/*.ts"
]
}
tsconfig.json
{
"compilerOptions": {
"outDir": "./build",
"module": "commonjs",
"target": "es6",
"strict": true
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules/alphalytics-data/src/**/*.ts"
]
}
jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['./src/'],
transform: {
'^.+\\.tsx?$': 'ts-jest'
},
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
};
1条答案
按热度按时间j8yoct9x1#
你模仿了
fs/promises
模块,所以你应该使用import * as fs from 'fs/promises';
而不是import { promises as fs } from 'fs';
fs
模块没有被模拟,因此fs.readdir
将是真实的实现。例如
tradeEvaluator.ts
:tradeEvaluator.test.ts
:试验结果: