将AutoMapper从v6升级到v9,并使用Resolution Context进行单元测试



我希望有人能帮助我。我们目前正在将AutoMapper从v6升级到v9-我们将升级到v10,但无法创建新的ResolutionContext会影响我们的单元测试。也就是说,在v9中,我们在单元测试AutoMapper转换器时仍然存在以下问题。。。

转换器类别:

public class FooBarConverter :
ITypeConverter<FooSourceObject, BarDestinationObject>
{
/// <inheritdoc/>
public virtual BarDestinationObjectConvert(FooSourceObjectsource, BarDestinationObjectdestination, ResolutionContext context)
{
EnsureArg.IsNotNull(source, nameof(source));
switch (source.Type)
{
case SomeType.None:
return context.Mapper.Map<NoneBarDestinationObject>(source);
case SomeType.FixedAmount:
return context.Mapper.Map<FixedBarDestinationObject>(source);
case SomeType.Percentage:
return context.Mapper.Map<PercentageBarDestinationObject>(source);
default:
throw new ArgumentOutOfRangeException(nameof(source));
}
}

之前在AutoMapper 6中,我们进行了以下单元测试(使用Xuit(:

public class FooBarConverterTests
{
private readonly FooBarConverter target;
private readonly Mock<IRuntimeMapper> mockMapper;
private readonly ResolutionContext resolutionContext;
public FooBarConverterTests()
{
this.mockMapper = new Mock<IRuntimeMapper>();
this.resolutionContext = new ResolutionContext(null, this.mockMapper.Object);
this.target = new FooBarConverter();
}
[Fact]
public void FixedAmountFooModel_ConvertsTo_FixedBarDomainModel()
{
// Arrange
var input = new Foo
{
Type = SomeType.FixedAmount
};
var expected = new DomainModels.FixedBarDestinationObject();
this.mockMapper.Setup(x => x.Map<FixedBarDestinationObject>(It.IsAny<FooSourceObjectsource>()))
.Returns(expected);
// Act
var actual = this.target.Convert(input, It.IsAny<BarDestinationObjectdestination>(), this.resolutionContext);
// Assert
actual.ShouldSatisfyAllConditions(
() => actual.ShouldNotBeNull(),
() => actual.ShouldBeAssignableTo<DomainModels.FixedBarDestinationObject>());
this.mockMapper.Verify(x => x.Map<DomainModels.FixedBarDestinationObject>(input));
}
}

从本质上讲,这运行得很好,但自从升级到v9以来,映射设置在通过解析上下文时丢失了。这意味着Mapper.Map<FixedBarDestinationObject>()的结果调用总是返回null

我知道ResolutionContext可能有轻微的变化,但我不知道如何解决这个问题并确保mock映射传递到底层转换器。

谢谢你的帮助或建议。

多亏了Lucian,我终于明白了这一点:

public class FooBarConverterTests
{
private readonly FooBarConverter target;
private readonly IMapper mapper;
public FooBarConverterTests()
{
this.mapper = this.GetMapperConfiguration().CreateMapper();

this.target = new FooBarConverter();
}
[Fact]
public void FixedAmountFooModel_ConvertsTo_FixedBarDomainModel()
{
// Arrange
var input = new Foo
{
Type = SomeType.FixedAmount
};
var expected = new DomainModels.FixedBarDestinationObject();
// Act
var actual = this.Mapper.Map<BarDestinationObjectdestination>(input);
// Assert
actual.ShouldSatisfyAllConditions(
() => actual.ShouldNotBeNull(),
() => actual.ShouldBeAssignableTo<DomainModels.FixedBarDestinationObject>());
}

private MapperConfiguration GetMapperConfiguration()
{
return new MapperConfiguration(opt =>
{
opt.AddProfile<CustomAutomapperProfile>();
opt.ConstructServicesUsing(t =>
{
if (t == typeof(FooBarConverter))
{
return this.target;
}
return null;
});
});
}
}

因此,我正在加载映射器配置文件(需要转换器(,并通过它调用转换器,这可以确保加载映射器概要文件。

作为奖励,这也意味着我完全取消了ResolutionContext的更新,并为升级到v10铺平了道路。

最新更新