Зарегистрируйте AutoMapper в модульных тестах XUnit в .Net Core 2.1 - PullRequest
0 голосов
/ 30 декабря 2018

Я получаю

"System.InvalidOperationException: Mapper уже инициализирован. Вы должны вызвать Initialize один раз для домена / процесса приложения."

ошибка при попытке зарегистрировать AutoMapper в моих классах модульных тестов с использованием тестовой среды XUnit.

У меня есть приложение с 3 слоями (Presentation - Business - Data).Как бизнес-уровень, так и уровень презентации имеют свои собственные классы профиля AutoMapper, которые зарегистрированы в классе, вызываемом при запуске.

Бизнес:

public class AutoMapperBusinessProfile : Profile
{
    public AutoMapperBusinessProfile()
    {
        CreateMap<WeatherEntity, WeatherModel>()
            .ForMember(x => x.Location, y => y.MapFrom(z => z.Name))
            .ForMember(x => x.Temperature, y => y.MapFrom(z => z.Main.Temp))

            // Here be mappings
            ...
    }
}

Презентация:

public class AutoMapperPresentationProfile : Profile
{
    public void RegisterMaps()
    {
        CreateMap<WeatherModel, MainViewModel>()
            .ForMember(dest => dest.TemperatureUom, x => x.MapFrom(src => src.TemperatureUom.ToString()));

        CreateMap<TrafficModel, MainViewModel>()
            .ConvertUsing<TrafficModelConverter>();

        // More mappings
        ...
    }
}

Запуск:

public static class AutoMapperConfiguration
{
    public static void RegisterAutoMapper()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.AddProfile<AutoMapperBusinessProfile>();
            cfg.AddProfile<AutoMapperPresentationProfile>();
        });
    }
}

Я могу нормально запустить приложение, все сопоставления верны.Тем не мение;при попытке запустить модульные тесты в моем коде я сначала получил нулевые ошибки ссылок на части отображения.Добавление кода для сброса и создания экземпляра профиля в конструкторах позволило одному классу модульных тестов работать правильно.

public WeatherBusinessTests()
{
    _service = new WeatherService();

    // Initialize AutoMapper in test class
    Mapper.Reset();
    Mapper.Initialize(cfg => cfg.AddProfile<AutoMapperBusinessProfile>());
}

Однако при запуске нескольких классов тестов с использованием метода Mapper.Reset () я получаю следующееошибка:

System.InvalidOperationException: преобразователь уже инициализирован.Вы должны вызывать Initialize один раз для домена / процесса приложения.

Запуск одного класса тестирования дает ожидаемые результаты.Как правильно зарегистрировать Automapper, чтобы все мои тесты могли выполняться рядом друг с другом и получать необходимую информацию о сопоставлениях?

// Calling AutoMapper in code
public TModel MapFromEntity(TEntity entity)
{
   var model = Mapper.Map<TModel>(entity);
   return model;
}

1 Ответ

0 голосов
/ 30 декабря 2018

Я считаю, что в этой части есть проблема, когда вы использовали RegisterMaps методы вместо конструктора AutoMapperPresentationProfile()

public class AutoMapperPresentationProfile : Profile
{
    public void RegisterMaps()
    {
        CreateMap<WeatherModel, MainViewModel>()
            .ForMember(dest => dest.TemperatureUom, x => x.MapFrom(src => src.TemperatureUom.ToString()));

        CreateMap<TrafficModel, MainViewModel>()
            .ConvertUsing<TrafficModelConverter>();

        // More mappings
        ...
    }
}

Преобразуйте его в

public class AutoMapperPresentationProfile : Profile
{
    public void AutoMapperPresentationProfile ()
    {
        CreateMap<WeatherModel, MainViewModel>()
            .ForMember(dest => dest.TemperatureUom, x => x.MapFrom(src => src.TemperatureUom.ToString()));

        CreateMap<TrafficModel, MainViewModel>()
            .ConvertUsing<TrafficModelConverter>();

        // More mappings
        ...
    }
}
...