如何为AutoMapperProfiles中的所有映射编写C#自动测试?
解决AutoMapper全映射测试问题
要批量测试所有MapperProfile中的映射,不用自己写复杂反射,直接利用AutoMapper自带的API就能实现,同时可以处理接口到类的映射场景,具体方案如下:
核心思路
- 通过
MapperConfiguration.GetAllTypeMaps()获取所有注册的映射关系(包括从Profile中添加的) - 针对每个映射的源类型,创建实例(接口用动态代理生成,类用构造函数或自动实例化工具)
- 调用
_mapper.Map()执行映射,验证是否能正常完成
完整测试代码示例
测试初始化
private IMapper _mapper; private MapperConfiguration _mappingConfig; [SetUp] public void Setup() { // 注册所有需要测试的Profile _mappingConfig = new MapperConfiguration(mc => { mc.AddProfile(new ProductProfile()); mc.AddProfile(new AppleProfile()); }); // 提前验证映射配置的合法性,避免无效配置进入测试 _mappingConfig.AssertConfigurationIsValid(); _mapper = _mappingConfig.CreateMapper(); }
全映射测试方法
[Test] public void TestAllMappings() { foreach (var typeMap in _mappingConfig.GetAllTypeMaps()) { var sourceInstance = CreateSourceInstance(typeMap.SourceType); if (sourceInstance == null) { Assert.Ignore($"无法创建源类型 {typeMap.SourceType.Name} 的实例,跳过该映射测试"); continue; } // 验证映射过程无异常 Assert.DoesNotThrow(() => _mapper.Map(sourceInstance, typeMap.SourceType, typeMap.DestinationType), $"映射 {typeMap.SourceType.Name} -> {typeMap.DestinationType.Name} 执行失败"); } }
实例创建工具方法(处理接口和类)
private object CreateSourceInstance(Type sourceType) { // 处理接口类型:用Moq生成动态代理实例 if (sourceType.IsInterface) { var mockType = typeof(Mock<>).MakeGenericType(sourceType); var mock = Activator.CreateInstance(mockType); return mockType.GetProperty("Object").GetValue(mock); } // 处理非抽象类:优先用无参构造函数创建 if (sourceType.IsClass && !sourceType.IsAbstract) { try { return Activator.CreateInstance(sourceType); } catch (MissingMethodException) { // 若类没有无参构造,可引入AutoFixture库自动生成实例 // 示例:return new Fixture().Create(sourceType); return null; } } return null; }
优化建议
如果遇到没有无参构造函数的类,推荐使用AutoFixture库,它能自动处理复杂类型的实例化,包括带参数构造函数的类、接口等,替换上述CreateSourceInstance方法即可:
private readonly Fixture _fixture = new Fixture(); private object CreateSourceInstance(Type sourceType) { try { return _fixture.Create(sourceType); } catch { return null; } }
内容的提问来源于stack exchange,提问作者giveyourtears
相关产品推荐
相关产品推荐

