.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内部配置接口
- 先获取真实的类型映射对象,然后Mock
IConfigurationProvider并转换为内部接口IInternalConfigurationProvider - 对内部接口的
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
相关产品推荐
相关产品推荐

