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

手动检查测试函数参数的最佳实践?TDD下参数检查代码臃肿疑问

关于TDD模式下参数校验代码的规范与优化方案

你的TDD实践完全符合规范——先写测试用例覆盖各类边界场景,再实现参数校验逻辑拦截错误,这种方式能有效保障代码健壮性,测试用例的覆盖度也做得很到位。但确实,重复的校验代码会让类的核心逻辑显得臃肿,下面给你几个可行的优化方向:

一、提取通用校验工具函数

把重复的校验逻辑(比如检查是否为整数、是否是单个参数、数值范围校验)抽成独立的工具函数,既能复用代码,也能让类的核心逻辑更清晰。

示例代码:

// 校验工具函数
const validateSingleNumberArg = (arg, name) => {
  if (typeof arg !== 'number') throw new Error(`${name} must be a number`);
  if (!Number.isInteger(arg)) throw new Error(`${name} must be an integer`);
};

const validatePositiveInteger = (num, name) => {
  validateSingleNumberArg(num, name);
  if (num < 1) throw new Error(`${name} must be greater than 0`);
};

const validateWithinRange = (num, min, max, name) => {
  validateSingleNumberArg(num, name);
  if (num < min || num > max) throw new Error(`${name} must be between ${min} and ${max}`);
};

// 优化后的Ship类
export default class Ship {
  constructor(shipLength, ...rest) {
    if (rest.length > 0) throw new Error('Must enter only 1 argument');
    validatePositiveInteger(shipLength, 'Length');
    
    this.length = shipLength;
    this.hits = Array(this.length).fill(false);
  }

  hit(location, ...rest) {
    if (rest.length > 0) throw new Error('Can only accept one argument');
    validateWithinRange(location, 0, this.length - 1, 'Location');
  
    this.hits[location] = true;
  }
}

二、使用静态类型检查(推荐)

如果项目可以引入TypeScript,或者用JSDoc配合编辑器的类型检查,能在编译/开发阶段就拦截大部分类型错误,减少运行时的校验代码。

TypeScript版本示例:

export default class Ship {
  public length: number;
  public hits: boolean[];

  constructor(shipLength: number) {
    // 仅保留无法通过静态类型检查覆盖的校验(比如数值范围、整数判断)
    if (!Number.isInteger(shipLength) || shipLength < 1) {
      throw new Error('Length must be a positive integer');
    }
    
    this.length = shipLength;
    this.hits = Array(this.length).fill(false);
  }

  hit(location: number): void {
    if (!Number.isInteger(location) || location < 0 || location >= this.length) {
      throw new Error('Location must be a non-negative integer within ship body');
    }
    this.hits[location] = true;
  }
}

TypeScript会在开发阶段就阻止你传入非number类型的参数,也会限制参数数量,这样运行时的校验代码就能大幅减少。

三、环境区分校验(可选)

如果这个类是项目内部使用的工具类,而非对外暴露的API,可以考虑只在开发环境保留校验代码,生产环境移除,减少性能开销:

constructor(shipLength, ...rest) {
  if (process.env.NODE_ENV === 'development') {
    if (rest.length > 0) throw new Error('Must enter only 1 argument');
    if (typeof shipLength !== 'number') throw new Error('Length must be a number');
    if (shipLength < 1) throw new Error('Length must be greater than 0');
    if (!Number.isInteger(shipLength)) throw new Error('Length must be an integer');
  }
  this.length = shipLength;
  this.hits = Array(this.length).fill(false);
}

总结:你的原始实现是规范的,但通过提取工具函数、引入静态类型检查等方式,可以有效减少代码冗余,同时不丢失校验能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 07:45:32