运行大量测试时,AutoMapper会将地图混淆吗?

时间:2013-04-17 15:16:27

标签: unity-container automapper mstest

我目前使用MSTest runner获得了大约1000个单元/集成测试的解决方案。我在使用AutoMapper时遇到的问题是,当VS在解决方案中运行所有测试时,由于以下的automapper异常,我会随机获得一些单元测试失败:

AutoMapper.AutoMapperMappingException: 

Mapping types:
String -> String
System.String -> System.String

Destination path:
CatalogResource.CultureCode

Source value:
en-US ---> System.InvalidCastException: Unable to cast object of type 'Model.Catalog' to type 'Model.CatalogResource'.

在代码中我没有Catalog to CatalogResource map,也没有尝试将它们映射到彼此。这种类型的异常在PROD中不会发生,并不会发生在集成测试中,每次运行测试时都不会发生,并且当它确实发生时,总会有不同的测试失败。此外,如果我只运行刚刚失败的测试,它们总是通过。我很难在本地继续复制它,但它在构建服务器上更频繁地发生,这很痛苦,因为它会阻止构建自动升级到下一个环境。

我也尝试将其添加到测试中,但它还没有解决问题:

   [ClassInitialize]
   public static void ClassInitialize(TestContext context)
   {
        Mapper.Reset();
   }

有什么想法吗?我们有4个不同的人对此采取刺无效,所以我现在请求你们大家帮忙。

谢谢!

编辑:

我目前使用静态类初始化配置,该静态类在服务的静态构造函数中调用。即。

static MyService()
        {
            AutoMapperBootstrapper.Initialize();
        }
...

internal static class AutoMapperBootstrapper
    {
 public static void Initialize()
        {
            ConfigureMappings();

            #if DEBUG
            Mapper.AssertConfigurationIsValid();
            #endif
        }
}

编辑#2:

在今天做一些修修补补的时候,我注意到这些随机故障只发生在<IDataReader, something else>地图上。例如:

 Mapper.CreateMap<IDataReader, Catalog>()
            .ForMember(m => m.CatalogID, opt => opt.MapFrom(src => src["CatalogID"]))               
            .ForMember(m => m.Title, opt => opt.MapFrom(src => src["Title"]))                   
            .ForMember(m => m.DateCreatedUTC, opt => opt.MapFrom(src => src["DateCreatedUTC"]))
            .ForMember(m => m.DateModifiedUTC, opt => opt.MapFrom(src => src["DateModifiedUTC"]))

...

不知道该怎么做但它看起来很相关。

1 个答案:

答案 0 :(得分:0)

我假设您从单元测试中调用AutoMapperBootstrapper.Initialize,并且您拥有映射配置的唯一位置位于ConfigureMappings?我无法解释你的问题,但显然你的单元测试之间有一些泄漏。我有类似的设置,这就是我做的......

我的初始化代码是

public static class MappingConfiguration
{
    public static void RegisterMappings()
    {
        Mapper.Initialize(x =>
            {
                x.AddProfile<MapperProfileOne>();
                x.AddProfile<MapperProfileTwo>();
            });
    }
}

这只是由应用程序调用(我不打扰测试RegisterMappings方法,因为它只有Initialize调用,我相信AutoMapper有效。我的单元测试(测试我的映射配置)如下:

[Test]
public void Initialise_ProfileOne_GeneratesNoErrors()
{
    Mapper.Initialize(x => x.AddProfile<MapperProfileOne>());
    Mapper.AssertConfigurationIsValid();
}

[Test]
public void Initialise_ProfileTwo_GeneratesNoErrors()
{
    Mapper.Initialize(x => x.AddProfile<MapperProfileTwo>());
    Mapper.AssertConfigurationIsValid();
}

个人资料的一个例子是:

public class MapperProfileOne : Profile
{
    protected override void Configure()
    {
        Mapper.CreateMap<Source, Destination>();
    }
}

我想知道如果你从单元测试中调用AutoMapperBootstrapper方法,它会以某种方式混淆(问题中没有足够的细节来确定这一点)。我认为不应该这样,但希望上面的代码中至少有一些东西可能会为你神奇地解决问题。