我有2个类,Class1应该映射到Class2。我使用 AutoMapper 进行映射。我想测试我的映射器配置,为此我使用 AutoFixture 。源类Class1具有IList<>类型的属性,目标类Class2具有类似的属性,但类型为IEnumerable<&gt ;.为了简化测试准备,我使用 AutoFixture (使用 AutoMoqCustomization )初始化源和目标对象。但在初始化IEnumerable<>类型的属性之后使用AutoFixture,AutoMapper无法映射属性。
错误文字:
映射类型时出错。
映射类型:Class1 - > Class2 ConsoleApplication1.Class1 - > ConsoleApplication1.Class2
类型地图配置:Class1 - > Class2 ConsoleApplication1.Class1 - > ConsoleApplication1.Class2
属性:项目
有人可以帮我配置AutoMapper或AutoFixture来使映射工作吗?作为一种解决方法,我可以将null分配给目标属性,但我不想在每个测试中执行此操作。
简化的代码示例:
public class AutoMapperTests
{
public static void TestCollectionsProperty()
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ItemClass1, ItemClass2>();
cfg.CreateMap<Class1, Class2>();
});
var src = new Class1();
src.Items = new List<ItemClass1>()
{
new ItemClass1() { Text = "111" },
new ItemClass1() { Text = "222" }
};
var fixture = new Fixture();
var dst = fixture.Create<Class2>();
Mapper.Map(src, dst); //Error at this line of code
}
}
public class Class1
{
public IList<ItemClass1> Items { get; set; }
}
public class Class2
{
public IEnumerable<ItemClass2> Items { get; set; }
}
public class ItemClass1
{
public string Text { get; set; }
}
public class ItemClass2
{
public string Text { get; set; }
}
答案 0 :(得分:1)
这本身并不是一个AutoFixture问题。您可以在没有自动混合的情况下重现它,而不是像这样创建dst
:
var dst = new Class2();
dst.Items = Enumerable.Range(0, 1).Select(_ => new ItemClass2());
这将产生类似的错误消息:
无法转换类型为'WhereSelectEnumerableIterator
2[System.Int32,Ploeh.StackOverflow.Q45437098.ItemClass2]' to type 'System.Collections.Generic.IList
的对象1 [Ploeh.StackOverflow.Q45437098.ItemClass2]'
这应该是不言自明的:WhereSelectEnumerableIterator<int, ItemClass2>
没有实现IList<ItemClass2>
。 AutoMapper尝试进行转换,但失败了。
最简单的解决方法可能是避免填充dst
:
var dst = new Class2();
如果你必须使用AutoFixture,你可以这样做:
var dst = fixture.Build<Class2>().OmitAutoProperties().Create();
然而,除非Class2
构造函数做了一些复杂的事情,否则在这种情况下我没有看到使用AutoFixture的重点。
另一方面,如果您需要填充dst
,则只需确保dst.Items
可转换为IList<ItemClass2>
。一种方法是这样的:
var dst = fixture.Create<Class2>();
dst.Items = dst.Items.ToList();
您可以创建自定义以确保自动生成,但如果您需要帮助,请提出一个新问题(如果您找不到已回答该问题的问题)。
答案 1 :(得分:0)
以下是您的问题的工作示例。正如@Mark Seemann所说,Mapper.CreateMap
已被弃用,因此这个例子正在使用新结构。
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ItemClass1, ItemClass2>();
cfg.CreateMap<Class1, Class2>();
});
var src = new Class1();
src.Items = new List<ItemClass1>()
{
new ItemClass1() { Text = "111" },
new ItemClass1() { Text = "222" }
};
var dest = Mapper.Map<Class1, Class2>(src);
答案 2 :(得分:0)
AM需要IList,因为您要映射到现有列表,并通过调用IList.Add来工作。