TDD结合DDD场景下,Invoice实体测试依赖过多的解决方案咨询
解决DDD实体测试依赖繁琐的方案
1. 用测试构建器(Test Builder)模式封装构造逻辑
- 把Invoice及其依赖实体的构造逻辑封装到专门的测试构建器中,预先为无关依赖设置好默认的极简实例(仅填充必填的ID或核心属性)
- 代码示例:
public class InvoiceTestBuilder { // 预先配置默认测试桩依赖 private Customer _customer = new CustomerTestBuilder().Build(); private List<InvoiceLine> _lines = new(); private InvoiceStatus _status = InvoiceStatus.Draft; // 链式方法按需修改关键属性 public InvoiceTestBuilder WithStatus(InvoiceStatus status) { _status = status; return this; } public InvoiceTestBuilder WithCustomer(Customer customer) { _customer = customer; return this; } public Invoice Build() { var invoice = new Invoice(_customer, _lines); // 若需特定状态,直接调用领域行为设置 if (_status == InvoiceStatus.Issued) { invoice.Issue(); } return invoice; } }
- 测试时仅需修改关键项:
var testInvoice = new InvoiceTestBuilder().WithStatus(InvoiceStatus.Issued).Build();
2. 为无关依赖使用极简测试桩
- 对与当前测试逻辑无关的依赖实体,无需完整初始化所有属性,只需满足构造函数的校验要求即可
- 比如依赖的Customer实体,仅填充
Id和Name等必填项,忽略BillingAddress、PaymentTerms等无关属性 - 若NHibernate的关联校验仅检查实体引用存在,甚至可以直接创建仅设置ID的空实体,无需维护其他属性
3. 谨慎调整实体校验时机
- 如果部分依赖校验仅为持久化需求、非核心业务规则,可将校验逻辑从构造函数移至领域服务或持久化层
- 例如将Invoice构造时需传入完整Customer实体的规则,改为仅传入CustomerID,保存时由领域服务校验Customer存在性,测试时直接传入合法ID即可
- 注意:此调整需确保不破坏业务一致性,仅针对非核心校验逻辑
4. 用内存数据库预置基础测试数据
- 利用NHibernate支持的内存数据库(如SQLite内存模式),预先批量插入常用基础依赖数据(如默认Customer、Product)
- 将初始化逻辑封装为测试前置方法,每个测试类启动时自动加载这些数据,测试时直接从数据库查询所需依赖实体
- 优势是贴近真实运行环境,比手动构造实体更高效,仅需维护少量测试数据脚本
内容的提问来源于stack exchange,提问作者Daggen
相关产品推荐
相关产品推荐

