AutoMapper Profiles and Unit Testing

I'm rolling over my AutoMappers from using one large AutoMapperConfiguration class to using actual profiles. Global now looks like so (forgive the Open/Close violation for now)

Mapper.Initialize(x =>
                       {
                          x.AddProfile<ABCMappingProfile>();
                          x.AddProfile<XYZMappingProfile>();
                          // etc., etc.
                  });

The key piece that got me over the top and the hurdle that had previously always stopped me from using profiles was my ninject binding. I could never get the binding to work. Prior I had this binding:

Bind<IMappingEngine>().ToConstant(Mapper.Engine).InSingletonScope();

I've since migrated to this binding:

Bind<IMappingEngine>().ToMethod(context => Mapper.Engine);

This now works, the app is functional, I have profiles, and things are good.

The hitch is now in my unit tests. Using NUnit, I'd setup my constructor dependencies.

private readonly IMappingEngine _mappingEngine = Mapper.Engine;

and then in my [Setup] method I'd construct my MVC controller and call the AutoMapperConfiguration class.

[SetUp]
public void Setup()
{
    _apiController = new ApiController(_mappingEngine);
    AutoMapperConfiguration.Configure();
}

which I've now modified to.

[SetUp]
public void Setup()
{
    _apiController = new ApiController(_mappingEngine);

    Mapper.Initialize(x =>
                          {
                              x.AddProfile<ABCMappingProfile>();
                              x.AddProfile<XYZMappingProfile>();
                              // etc., etc.
                          });
}

Unfortunately, this does not seem to work. The mappings do not appear to be getting picked up as when I hit a method that uses mappings, AutoMapper throws an exception stating the mapping doesn't exist. Any suggestions on how/what to change the the mapper definition/injection in the test to resolve this? I'm guessing the definition of the IMappingEngine field is my problem but unsure of what options I have.

Thanks


Issue that you have is result of using static Mapper.Engine which is some kind of singleton that contains configuration for AutoMapper. By convention, Mapper.Engine should not be changed after it has been configured. So, if you'd like to configure Automapper by providing AutoMapper.Profiler for each of unittest, you should avoid using it.

Changes are quite simple: add to instance your class AutoMapperConfiguration it's own instance AutoMapper.MappingEngine instead of using global static Mapper.Engine .

public class AutoMapperConfiguration 
{
    private volatile bool _isMappinginitialized;
    // now AutoMapperConfiguration  contains its own engine instance
    private MappingEngine _mappingEngine;

    private void Configure()
    {
        var configStore = new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers());

        configStore.AddProfile(new ABCMappingProfile());
        configStore.AddProfile(new XYZMappingProfile());

        _mappingEngine = new MappingEngine(configStore);

        _isMappinginitialized = true;
    }

    /* other methods */
}

ps: full sample is here

链接地址: http://www.djcxy.com/p/12906.html

上一篇: 代码合同警告“确保未经证实”涉及锁定时

下一篇: AutoMapper配置文件和单元测试