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

单元测试中通用代码的合理存放位置咨询

我来帮你分析这段复用代码的最佳放置方式,结合最小惊讶原则和测试实践来拆解每个选项:

首先先贴出你提到的复用代码:

Guid product1Guid = Guid.NewGuid();
Guid product2Guid = Guid.NewGuid();
Products = new List<Product>();
var product1 = new Product(product1Guid, "Product 1");
var product2 = new Product(product2Guid, "Product 2");
Products.Add(product1);
Products.Add(product2);

各选项逐一分析

1) OneTimeSetup方法

不推荐的核心原因你已经点透了:Product是可变类型,一旦某个测试意外修改了实例状态(比如修改产品名称、新增属性值),会直接污染后续所有测试的前置数据,彻底破坏测试的隔离性原则——每个测试都应该独立运行,不受其他测试的执行影响。

2) 测试类内部创建返回列表的方法

反对的理由很合理:这段代码是生成真实的Product实例,并非模拟桩代码,专门写个方法属于过度设计,反而会让测试代码变得冗余啰嗦,不符合测试代码的简洁性要求。

3) 每个测试方法中重复代码

确实违反DRY原则,一旦后续需要修改Product的初始化逻辑(比如新增必填属性、调整命名规则),你得手动修改5个测试方法,不仅麻烦还容易漏改,维护成本极高。

4) 创建独立于测试类的Helper类(返回该列表)

这其实是测试实践里非常常规且推荐的做法!


推荐方案:独立Test Data Helper类

为什么说这符合最小惊讶原则?

  • 其他开发者看到TestProductHelper.GetSampleProducts()这类方法,一眼就能明白这是用来生成测试专用的产品数据,不会产生歧义;
  • 每次调用Helper方法都会生成全新的Guid和Product实例,完美解决了可变对象的状态污染问题,保证每个测试都拿到干净独立的前置数据;
  • 测试数据的生成逻辑集中在一处,既遵守了DRY原则,未来修改规则时只需调整Helper类,所有依赖的测试都会自动生效,维护成本极低。

举个简单的Helper类示例:

public static class TestProductHelper
{
    public static List<Product> GetSampleProducts()
    {
        Guid product1Guid = Guid.NewGuid();
        Guid product2Guid = Guid.NewGuid();
        var products = new List<Product>();
        var product1 = new Product(product1Guid, "Product 1");
        var product2 = new Product(product2Guid, "Product 2");
        products.Add(product1);
        products.Add(product2);
        return products;
    }
}

之后在每个测试方法里直接调用即可:

Products = TestProductHelper.GetSampleProducts();

这种方式简洁、安全、易维护,完全符合让后续开发者一目了然的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:06:21