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

如何对使用IMappingAction的AutoMapper Profile进行单元测试?

无需DI容器的AutoMapper IMappingAction单元测试方案

针对你遇到的两个测试问题,有两种无需依赖Microsoft DI容器的轻量化解决方案:

方案一:手动实例化IMappingAction并直接绑定到映射配置

这种方式跳过AutoMapper的服务构造逻辑,直接把带依赖的Action实例传给映射配置:

  1. 先Mock你的ISerialNumberProvider服务:

    var mockSerialNumberProvider = new Mock<ISerialNumberProvider>();
    // 预设Mock的返回值,比如:
    mockSerialNumberProvider.Setup(p => p.GenerateSerialNumber(It.IsAny<Student>()))
                            .Returns("TEST-SERIAL-001");
    
  2. 手动实例化SetSerialNumberAction,注入Mock的服务:

    var setSerialNumberAction = new SetSerialNumberAction(mockSerialNumberProvider.Object);
    
  3. 构建MapperConfiguration时,直接将Action绑定到对应的映射:

    var config = new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<Student, StudentDto>()
            .AfterMap(setSerialNumberAction); // 直接传入已实例化的Action
    });
    
  4. 创建Mapper并执行映射,最后验证逻辑:

    var mapper = config.CreateMapper();
    var student = new Student { /* 测试数据 */ };
    var dto = mapper.Map<StudentDto>(student);
    
    // 验证SerialNumber是否正确
    Assert.Equal("TEST-SERIAL-001", dto.SerialNumber);
    // 验证服务方法是否被调用
    mockSerialNumberProvider.Verify(p => p.GenerateSerialNumber(student), Times.Once);
    

方案二:用ConstructServicesUsing自定义服务构造逻辑

如果想复用原有的Profile配置,不想重复编写映射规则,可以通过ConstructServicesUsing告诉AutoMapper如何创建依赖实例:

  1. 同样先MockISerialNumberProvider:

    var mockSerialNumberProvider = new Mock<ISerialNumberProvider>();
    mockSerialNumberProvider.Setup(p => p.GenerateSerialNumber(It.IsAny<Student>()))
                            .Returns("TEST-SERIAL-002");
    
  2. 构建配置时,通过ConstructServicesUsing指定类型构造逻辑:

    var config = new MapperConfiguration(cfg =>
    {
        cfg.ConstructServicesUsing(type =>
        {
            // 当AutoMapper需要创建SetSerialNumberAction时,手动注入Mock服务
            if (type == typeof(SetSerialNumberAction))
            {
                return new SetSerialNumberAction(mockSerialNumberProvider.Object);
            }
            // 测试场景下一般不需要处理其他类型,若有需要可扩展
            throw new InvalidOperationException($"无法构造类型: {type.FullName}");
        });
        // 加载你原本的Profile
        cfg.AddProfile<StudentMappingProfile>();
    });
    
  3. 后续的映射和验证步骤和方案一一致,直接创建Mapper并验证即可。

这两种方案都能解决"无参数构造函数"的报错,同时让你完全控制ISerialNumberProvider的Mock实例,方便验证映射逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 05:42:15