在Automapper测试中使用ResolutionContext

问题描述 投票:0回答:2

如何使用

ResolutionContext
测试 Automapper ITypeConverter 转换器?

我有一个复杂的转换器,想明确地测试它。 它需要一个参数

ResolutionContext
,我无法到达,也无法创建或模拟。 可以吗?

public class MyConverter : ITypeConverter<SourceType, TargetType>
{
    public TargetType Convert(SourceType source, TargetType destination, ResolutionContext context)
    {
       ...complicated code...
    }
}

编辑/澄清:我试图调用

myMapper.Map(...
,但这些只是“MyConverter.Convert”函数。
我知道这可以被认为是错误的测试方法,因为应该只测试公共方法,而这个类/方法只是由于技术原因而公开的,从面向对象的角度来看应该真正是私有的。但该讨论是针对另一个论坛的。

c# .net-core automapper automapper-12
2个回答
2
投票

AutoMapper 本身的TypeConverter单元测试的

源代码
表明它们遵循常规流程:

  • 设置
    MapperConfiguration
  • 从中创建一个
    Mapper
  • 调用
    Map
    重载之一。

通过这样做,AutoMapper 负责将

ResolutionContext
传递给
Convert
方法。

下面的代码显示了

Convert
方法如何接收具有预配置
ResolutionContext
字典的
Items

var configuration = new MapperConfiguration(
    o => o.CreateMap<SourceType, TargetType>().ConvertUsing<MyConverter>()
    // More mappings go here.
    );

var mapper = configuration.CreateMapper();

var source = new SourceType 
{
    Name = "foo" 
};

var target = mapper.Map<TargetType>(
    source,
    o =>
    {
        o.Items["foo"] = "bar";
    });

Console.WriteLine(target.Name); // bar
public class SourceType
{
    public string Name { get; set; }
}

public class TargetType
{ 
    public string Name { get; set; }
}

public class MyConverter : ITypeConverter<SourceType, TargetType>
{
    public TargetType Convert(SourceType source, TargetType destination, ResolutionContext context)
    {
        // Complicated code goes here.
    
        return new TargetType
        {
            Name = (string)context.Items[source.Name]
        };
    }
}

0
投票

如果您的自定义转换器有任何依赖项,这可能是一个可能的解决方法:

根据 Automapper,ResolutionContext 没有公共构造函数,因此不可能模拟它,也无法实例化。我们必须使用实际的映射器来测试具有依赖项的自定义转换器。

这是示例代码,希望有所帮助:

public class MyConverterTests
{
    #region Private Variables
    private static readonly MyCustomConverter _myCustomConverter;
    private static readonly Mock<DependencyA> _dependencyA;
    private readonly IMapper _mapper;
    #endregion

    static MyConverterTests()
    {
        _dependencyA = new Mock<DependencyA>();
        _myCustomConverter = new MyCustomConverter(_dependencyA.Object);
    }

    public MyConverterTests()
    {
        var mapperConfiguration = new MapperConfiguration(cfg => cfg.AddProfile<CustomMapperProfile>());
        _mapper = new AutoMapper.Mapper(mapperConfiguration);
    }

    [Fact]
    public void TestCaseA()
    {
        // Do Testing
    }

    public class CustomMapperProfile : Profile
    {
        public CustomMapperProfile()
        {
            CreateMap<Source, Destination>()
                .ConvertUsing(_myCustomConverter);
        }
    }
}

public class MyCustomConverter : ITypeConverter<Source, Destination>
{
    public MyCustomConverter(DependencyA dependency)
    {

    }

    public Destination Convert(Source source, Destination destination, ResolutionContext context)
    {
        throw new System.NotImplementedException();
    }
}

public class DependencyA
{

}

public class Destination
{

}

public class Source
{

}
© www.soinside.com 2019 - 2024. All rights reserved.