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

.NET Core升级AutoMapper至12.0.1后单元测试FindTypeMapFor失败

AutoMapper升级后单元测试报错问题

我们在.NET Core项目中将AutoMapper从10.1.1版本升级至12.0.1版本后,调用FindTypeMapFor方法出现错误。添加AutoMapper.Internal命名空间后,业务代码恢复正常,但单元测试执行失败,报错信息如下:

Unsupported expression: ... => ....Internal()
Extension methods (here: InternalApi.Internal) may not be used in setup / verification expressions

业务代码

private IMapper _mapper;

public UtilityService(IMapper mapper)
{
    _mapper = mapper;
}

public string ToSearchAllQuery<T1, T2>(T2 dtoModel, SearchFilterModel filterModel) 
    where T1 : class
    where T2 : class
{
    var props = typeof(T1).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(SearchAllAttribute)));
    var map = _mapper.ConfigurationProvider.Internal().FindTypeMapFor<T1, T2>();
}       

单元测试代码

private Fixture fixture = new Fixture();
private Mock<IMapper> _mapper;
private UtilityService _utilityService;

[SetUp]
public void UtilityServiceTestsSetUp()
{
    _mapper = new Mock<IMapper>(MockBehavior.Strict);
    _utilityService = new UtilityService(_mapper.Object);
}

[SetUp]
public void SearchAllSetup()
{
    var locMappingProfile = new ChaseReportLocationMappingProfile();
    var configuration = new MapperConfiguration(cfg => cfg.AddProfile(locMappingProfile));
    var mapper = new Mapper(configuration);
    var map = mapper.ConfigurationProvider.Internal().FindTypeMapFor<ChaseReportLocationModel, ChaseReportLocationDTO>();
    _mapper.Setup(x => x.ConfigurationProvider.Internal().FindTypeMapFor<ChaseReportLocationModel, ChaseReportLocationDTO>()).Returns(map);
}

解决方法

Moq不允许在Setup或验证表达式中调用扩展方法,这是单元测试报错的核心原因。可以通过以下两种方式修复:

方案一:Mock内部配置接口

  1. 先获取真实的类型映射对象,然后MockIConfigurationProvider并转换为内部接口IInternalConfigurationProvider
  2. 对内部接口的FindTypeMapFor方法进行Setup,最后将Mock的配置提供者关联到IMapper的Mock上

修改后的单元测试代码:

[SetUp]
public void SearchAllSetup()
{
    var locMappingProfile = new ChaseReportLocationMappingProfile();
    var configuration = new MapperConfiguration(cfg => cfg.AddProfile(locMappingProfile));
    var map = configuration.Internal().FindTypeMapFor<ChaseReportLocationModel, ChaseReportLocationDTO>();

    // Mock配置提供者,并转换为内部接口
    var configProviderMock = new Mock<IConfigurationProvider>();
    configProviderMock.As<IInternalConfigurationProvider>()
                     .Setup(x => x.FindTypeMapFor<ChaseReportLocationModel, ChaseReportLocationDTO>())
                     .Returns(map);

    // 将Mock的配置提供者绑定到IMapper
    _mapper.Setup(x => x.ConfigurationProvider).Returns(configProviderMock.Object);
}

方案二:避免使用Internal API(推荐)

AutoMapper的Internal API属于未公开的内部接口,版本迭代时容易出现兼容性问题。如果业务场景允许,尽量使用AutoMapper提供的公开API替代Internal().FindTypeMapFor的调用方式,从根源上避免此类问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 21:37:08