c# - 修改现有的 AutoMapper 类型映射(用于单元测试)

标签 c# unit-testing automapper

我使用 AssertConfigurationIsValid对我的映射配置文件进行单元测试的方法。为了让它接受我的映射,我需要明确忽略未映射的目标属性。这会污染我的映射代码并降低其可读性。由于这只需要通过 AssertConfigurationIsValid 的单元测试才能通过,因此我想将“忽略”代码移至同一单元测试。

考虑来自某些映射配置文件类的以下映射代码:

CreateMap<SourceType, DestinationType>()
   // here goes some actual mapping code:
   .ForMember(dest => dest.DestMember, opt => opt.MapFrom(src => src.SourceMember))
   // and then go the explicitly ignored unmapped dest members,
   // just for AssertConfigurationIsValid to pass:
   .ForMember(dest => dest.IgnoredMember, opt => opt.Ignore());

我想将后面的代码移动到一个单元测试方法中,所以它看起来像下面这样:

[TestMethod]
public void TestMappingConfiguration()
{
  Mapper.AddProfile<MyProfile>();
  Mapper.FindTypeMapFor<SourceType, DestinationType>()
    .ForMember(dest => dest.IgnoredMember, opt => opt.Ignore());
  Mapper.AssertConfigurationIsValid(MyProfile.Name);
}

Mapper 类中已经有 FindTypeMapFor 方法,但我找不到将忽略的属性添加到映射的好方法。这可能吗?

最佳答案

我已经成功地完成了我想做的事情。 这是带有扩展方法的主类,用于将忽略的属性添加到现有 map :

  static class TypeMapExtensions
  {
    public static TypeMap<TSource, TDestination> AddIgnoredMember<TSource, TDestination>(
      this TypeMap<TSource, TDestination> typeMap, 
      Expression<Func<TDestination, object>> accessorExpression)
    {
      MemberInfo memberInfo = ReflectionHelper.FindProperty(accessorExpression);
      IMemberAccessor memberAccessor = memberInfo.ToMemberAccessor();
      var propertyMap = new PropertyMap(memberAccessor);
      propertyMap.Ignore();
      AddPropertyMap(typeMap.Map, propertyMap);
      return typeMap;
    }

    private static void AddPropertyMap(TypeMap typeMap, PropertyMap propertyMap)
    {
      typeMap.AddPropertyMap(propertyMap);
      if (typeMap.HasDerivedTypesToInclude())
      {
        IEnumerable<TypeMap> derivedMaps = GetDerivedMaps(typeMap);
        foreach (var derivedMap in derivedMaps)
          derivedMap.AddInheritedPropertyMap(propertyMap);
      }
    }

    private static IEnumerable<TypeMap> GetDerivedMaps(TypeMap typeMap)
    {
      return Mapper.GetAllTypeMaps().Where(
        map =>
          (map.Profile == typeMap.Profile) &&
          (typeMap.TypeHasBeenIncluded(map.SourceType, map.DestinationType)));
    }
  }

类 TypeMap 只不过是原始 TypeMap 的包装器。通用版本的重点是允许流利的语法(见下文)。

从 AutoMapper 源代码中借用的 ReflectionHelper 类。它依赖于 AutoMapper.Internal 命名空间中的其他五个类,因此它们也被借用。

最后,所有这些让我可以编写以下代码:

TypeMap<SourceType, DestinationType>.Get()
  .AddIgnoredMember(dest => dest.IgnoredMember)
  .AddIgnoredMember(dest => dest.AnotherIgnoredMember);

关于c# - 修改现有的 AutoMapper 类型映射(用于单元测试),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15978685/

相关文章:

c# - API 在 reviews 属性中返回 null

c# - 是否可以直接打开Outlook session 窗口?

c# - 学习 Entity Framework 6 命令树拦截器

java - 用户输入的单元测试 - Java

c# - 什么是好的、免费的 C# 单元测试覆盖工具?

c# - 具有嵌套子列表的自动映射器

c# - 是否可以在 App.config 文件中的 appSettings 中引用主目录?

c# - 网络服务错误 500 内部错误 asp.net

javascript - 单元测试失败,错误为 "Cypress command timeout of ' 超过 4000 毫秒。”

c# - AutoMapper 3.1.1 和 Entity Framework 6.1 代理对象