弱类型语言中单元测试覆盖范围界定:以JS函数baz()测试为例
问题解答
先明确核心原则:单元测试的本质是验证函数在约定的契约范围内的行为是否符合预期,而契约的边界完全由你根据代码的使用场景来定义。
针对示例1、3、4:类型不合法的输入
这些属于违反「类型契约」的情况。如果你的baz()函数契约明确要求入参index是非负整数,那传入数组、布尔值、字符串(哪怕是看起来像数字的'0')都属于调用方违反契约的错误行为。这种情况下,单元测试不需要覆盖这些场景——因为我们默认调用方会遵守契约,只需要测试合法类型输入的正常逻辑即可。
但如果你的代码是对外暴露的公共API,或者调用方可能出现误传类型的情况,那你应该在代码中添加类型校验逻辑(比如用Number.isInteger(index)判断),这时候才需要为这些非法类型输入编写测试用例,验证校验逻辑是否能正确拦截或处理。
针对示例2:类型合法但索引越界的输入
这属于违反「逻辑边界契约」的情况,要不要关注取决于你的契约定义:
- 如果契约明确规定
index必须处于0到bar.length - 1之间,那调用方传入超出范围的索引(比如数组大小为2时传5)属于违反契约,单元测试不需要覆盖这种场景,只需要验证合法范围内的索引是否能正确设置值即可。 - 但如果你的函数需要对越界情况做容错处理(比如静默忽略、抛出明确的错误提示、或者做其他兜底逻辑),那你必须为这种场景编写单元测试,确保越界时的行为符合预期。
要不要在代码中处理示例2的情况?
这完全看你的代码使用场景:
- 如果是内部私有函数,调用方都是团队内部成员且能保证传入合法索引,那不需要额外处理,契约就是「调用方必须传入合法范围内的索引」。
- 如果是公共API、或者调用方可能出现误传的情况,建议添加边界校验逻辑,比如:
这种情况下,就需要编写单元测试来验证:当传入越界索引时,是否会正确抛出指定的错误。baz(index) { if (!Number.isInteger(index) || index < 0 || index >= this.bar.length) { throw new RangeError('index必须是数组范围内的非负整数'); } this.bar[index] = true; }
内容的提问来源于stack exchange,提问作者Khaled
相关产品推荐
相关产品推荐

