2013-04-22 20 views
7

Przetaczam moje AutoMappery, korzystając z jednej dużej klasy AutoMapperConfiguration do korzystania z rzeczywistych profili. Globalny teraz wygląda tak (wybacz/Zamknij naruszenie otwarty do teraz)Profile AutoMapperów i testowanie jednostek

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

Kluczowym elementem, który dostał mnie w górę i płotek, które wcześniej zawsze zatrzymał mnie z wykorzystaniem profili był wiążący mój ninject. Nigdy nie mogłem uzyskać wiążącej mocy do działania. Wcześniej miałem tego wiązania:

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

mam od migracji do tego wiązania:

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

to teraz działa, aplikacja działa, mam profili, a rzeczy są dobre.

Zaczep jest teraz w moich testach jednostkowych. Używając NUnit, skonfigurowałbym zależności od konstruktora.

private readonly IMappingEngine _mappingEngine = Mapper.Engine; 

a następnie w mojej metodzie [Setup] skonstruowałbym kontroler MVC i zadzwoniłam do klasy AutoMapperConfiguration.

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

którą teraz zmodyfikowałem.

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

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

Niestety, to nie działa. Odwzorowania nie wydają się być zbierane, ponieważ gdy uderzę w metodę, która używa odwzorowań, AutoMapper zgłasza wyjątek stwierdzający, że mapowanie nie istnieje. Wszelkie sugestie dotyczące tego, jak/co zmienić definicję/wstrzykiwacz w teście, aby rozwiązać ten problem? Zgaduję, że definicja pola IMappingEngine jest moim problemem, ale nie wiem, jakie mam opcje.

Dzięki

Odpowiedz

3

problem, który masz jest wynikiem zastosowania statycznego Mapper.Engine który jest pewnego rodzaju Singleton, który zawiera konfigurację dla AutoMapper. Zgodnie z konwencją, Mapper.Engine nie należy zmieniać po skonfigurowaniu. Jeśli więc chcesz skonfigurować Automapper, podając AutoMapper.Profiler dla każdego z unittest, powinieneś go unikać.

Zmiany są dość proste: dodaj instancję klasy AutoMapperConfiguration do własnej instancji AutoMapper.MappingEngine zamiast używać globalnej statycznej wartości 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

+0

Przepraszam, że nie dostał z powrotem do Ciebie jeszcze. Przeprowadziłem test, a twój Git działa, ale gdy tylko spróbuję wyciągnąć silnik jako parametr konstruktora, rzeczy znikają z szyn. Dziś wieczorem wrócę do dalszych testów. – Khepri

+0

Dziś rano sprawdziłem, że jako samodzielne rozwiązanie, twój git spełnia to, czego oczekujesz. Jednak w moim scenariuszu, w którym próbuję przekazać instancję IMappingEngine jako parametr konstruktora wykorzystujący program Ninject, nadal nie otrzymuję inicjowanych mapowań. Wziąłem git i dodałem metodę, aby wyrejestrować zainicjowany MappingEngine i próbowałem przekazać to jako parametr konstruktora. Wyniki były takie same. – Khepri

+0

Czy próbowałeś zamienić _all_ calls/refences na 'Mapper' (' Mapper.Initialize', 'Mapper.Engine', itd.) Z nową autonomiczną instancją' MappingEngine'? – Akim