You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为接收argv的命令行write函数编写测试并实现全覆盖?

解决Jest测试write函数时的进程异常问题并实现100%覆盖率

问题根源

你遇到的jest worker encountered 4 child process exceptions错误,本质是write函数里直接调用了process.exit()——Jest的测试worker进程被强制终止,多次重试后触发了上限。另外未隔离process.argv修改、未mock文件读写副作用,也会导致测试不稳定。

分步解决方案

1. 拆分业务逻辑与进程退出逻辑

把process.exit()从write函数中剥离,移到脚本入口文件,让write专注于业务逻辑,抛出错误而非直接终止进程:

// src/write.js
import fs from 'fs';
import { figmaToChakra } from './figmaToChakra.js';

export function write() {
  // 从命令行参数获取路径
  const [inputPath, outputPath] = process.argv.slice(2);
  
  // 参数校验
  if (!inputPath || !outputPath) {
    throw new Error('请传入输入文件路径和输出文件路径');
  }

  try {
    // 读取输入文件
    const rawData = fs.readFileSync(inputPath, 'utf8');
    // 转换数据
    const transformedData = figmaToChakra(rawData);
    // 写入输出文件
    fs.writeFileSync(outputPath, JSON.stringify(transformedData, null, 2));
    return transformedData;
  } catch (err) {
    throw new Error(`处理失败: ${err.message}`);
  }
}

// bin/figma-to-chakra.js(脚本入口)
#!/usr/bin/env node
import { write } from '../src/write.js';

write()
  .then(() => {
    console.log('转换完成');
    process.exit(0);
  })
  .catch((err) => {
    console.error(err);
    process.exit(1);
  });

2. Mock文件系统与依赖

用Jest mockfs模块和figmaToChakra函数,避免实际读写文件,隔离外部依赖:

// __tests__/write.test.js
import { write } from '../src/write.js';
import fs from 'fs';
import { figmaToChakra } from '../src/figmaToChakra.js';

// Mock文件系统
jest.mock('fs');
// Mock转换函数
jest.mock('../src/figmaToChakra.js', () => ({
  figmaToChakra: jest.fn(() => ({ theme: 'mock-chakra-theme' }))
}));

3. 隔离process.argv修改

在每个测试用例前后保存、恢复原始process.argv,避免测试间互相影响:

describe('write函数测试', () => {
  const originalArgv = [...process.argv];

  beforeEach(() => {
    jest.clearAllMocks();
    // 恢复原始命令行参数
    process.argv = [...originalArgv];
  });

4. 编写全分支测试用例

覆盖所有代码路径,确保100%覆盖率:

// 测试正常流程
  test('成功读取、转换并写入文件', () => {
    // 设置测试用命令行参数
    process.argv.push('./input.json', './output.json');
    // Mock读文件返回值
    fs.readFileSync.mockReturnValue(JSON.stringify({ figmaTheme: 'test-data' }));

    const result = write();

    expect(fs.readFileSync).toHaveBeenCalledWith('./input.json', 'utf8');
    expect(figmaToChakra).toHaveBeenCalledWith(JSON.stringify({ figmaTheme: 'test-data' }));
    expect(fs.writeFileSync).toHaveBeenCalledWith(
      './output.json',
      JSON.stringify({ theme: 'mock-chakra-theme' }, null, 2)
    );
    expect(result).toEqual({ theme: 'mock-chakra-theme' });
  });

  // 测试参数缺失
  test('未传入路径时抛出错误', () => {
    expect(() => write()).toThrow('请传入输入文件路径和输出文件路径');
  });

  // 测试输入文件不存在
  test('输入文件不存在时抛出错误', () => {
    process.argv.push('./non-exist.json', './output.json');
    fs.readFileSync.mockImplementation(() => {
      throw new Error('ENOENT: 文件不存在');
    });

    expect(() => write()).toThrow('处理失败: ENOENT: 文件不存在');
  });

  // 测试转换函数失败
  test('转换数据失败时抛出错误', () => {
    process.argv.push('./input.json', './output.json');
    fs.readFileSync.mockReturnValue('invalid-data');
    figmaToChakra.mockImplementation(() => {
      throw new Error('数据格式错误');
    });

    expect(() => write()).toThrow('处理失败: 数据格式错误');
  });

  // 测试写入文件失败
  test('写入输出文件失败时抛出错误', () => {
    process.argv.push('./input.json', './output.json');
    fs.readFileSync.mockReturnValue(JSON.stringify({ figmaTheme: 'test-data' }));
    fs.writeFileSync.mockImplementation(() => {
      throw new Error('权限不足');
    });

    expect(() => write()).toThrow('处理失败: 权限不足');
  });
});

验证与运行

执行测试命令:

jest __tests__/write.test.js --coverage

此时测试不会再触发进程退出异常,且能覆盖所有代码分支,达到100%覆盖率。

内容的提问来源于stack exchange,提问作者Hasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 15:38:16