1

我目前有一个使用 MSTest 运行器进行大约 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 到 CatalogResource 的映射,也没有尝试将它们相互映射。这种类型的异常不会发生在 PROD 中,不会发生在集成测试中,每次运行测试时都不会发生,当它发生时,总是不同的测试失败。此外,如果我只运行刚刚失败的测试,它们总是会通过。我很难始终如一地在本地复制它,但它在构建服务器上发生得更频繁,这很痛苦,因为它会阻止构建自动升级到下一个环境。

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

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

有任何想法吗?我们已经有 4 个不同的人对此进行了尝试,但无济于事,所以我现在向你们伟大的人寻求帮助。

谢谢!

编辑:

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

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"]))

...

还不知道该怎么做,但它似乎很相关。

4

1 回答 1

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从单元测试中调用该方法,它会以某种方式感到困惑(问题中没有足够的细节来确定这一点)。我认为不应该,但希望上面的代码中至少有一些东西可以神奇地为您解决问题。

于 2013-04-18T02:38:22.017 回答