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

单元测试复用模拟数据:Moq创建AssetIndexSummaryDto遇空引用异常

解决DTO测试假数据的空引用问题+优雅写法

问题根源:用Moq创建POCO是错误用法

Moq的核心作用是模拟接口、抽象类或带虚成员的类,用来隔离依赖。而AssetIndexSummaryDto作为普通POCO(无虚属性/方法),用Moq生成的Mock对象本质是代理类,即使调用SetupAllProperties(),未显式赋值的引用类型属性依然会返回null——当映射逻辑访问这些未初始化的属性时,就会触发NullReferenceException。

直接解决空引用:放弃Moq,改用正确的DTO实例化方式

1. 最简方案:直接实例化赋值

var testDto = new AssetIndexSummaryDto
{
    Id = 1,
    Name = "测试资产索引",
    // 按需填充所有映射逻辑会用到的属性
};

2. 复用性方案:Builder模式封装

如果多个测试需要创建结构类似的DTO,写一个Builder类统一管理数据生成,避免重复复制粘贴:

public class AssetIndexSummaryDtoBuilder
{
    // 设置默认值,减少重复赋值
    private int _id = 1;
    private string _name = "默认资产索引";
    private DateTime _createTime = DateTime.Now;

    // 链式修改属性
    public AssetIndexSummaryDtoBuilder WithId(int id)
    {
        _id = id;
        return this;
    }

    public AssetIndexSummaryDtoBuilder WithName(string name)
    {
        _name = name;
        return this;
    }

    public AssetIndexSummaryDtoBuilder WithCreateTime(DateTime time)
    {
        _createTime = time;
        return this;
    }

    // 生成最终实例
    public AssetIndexSummaryDto Build()
    {
        return new AssetIndexSummaryDto
        {
            Id = _id,
            Name = _name,
            CreateTime = _createTime
            // 其他属性按默认值或已修改的值填充
        };
    }
}

测试中使用:

// 创建默认实例
var defaultDto = new AssetIndexSummaryDtoBuilder().Build();

// 创建自定义属性的实例
var customDto = new AssetIndexSummaryDtoBuilder()
    .WithId(100)
    .WithName("自定义索引")
    .Build();

3. 高效方案:用测试数据生成库

如果需要大量随机/多样化的测试数据,用AutoFixture或Bogus这类工具自动填充POCO:

AutoFixture示例

var fixture = new Fixture();
// 自动生成所有属性的有效值
var autoGeneratedDto = fixture.Create<AssetIndexSummaryDto>();

// 手动覆盖特定属性
autoGeneratedDto.Name = "手动修改名称";

Bogus示例(生成更真实的随机数据)

var faker = new Faker<AssetIndexSummaryDto>()
    .RuleFor(dto => dto.Id, f => f.Random.Int(1, 1000))
    .RuleFor(dto => dto.Name, f => f.Commerce.ProductName())
    .RuleFor(dto => dto.CreateTime, f => f.Date.Past());

var realisticDto = faker.Generate();

优雅管理测试假数据的原则

  • 拒绝重复硬编码:把通用测试数据(比如边界值、默认值)抽成静态常量或方法。
  • POCO用专门的工具生成:Moq留给依赖模拟,测试数据用Builder、AutoFixture/Bogus更合适。
  • 单一职责:每个Builder/Factory只负责对应DTO/Entity的数据生成,维护更简单。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:31:05