2013-04-17 68 views
0

我目前擁有使用MSTest亞軍的大約1000個單元/集成測試的解決方案。林與AutoMapper遇到的問題是,當我有VS運行的解決方案的所有測試中,我會隨機得到一些單元測試失敗是由於以下automapper例外: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'. 

在代碼中,我沒有一個目錄CatalogResource地圖也不是我試圖將它們映射到對方。這種類型的異常不會發生在PROD中,不會發生在集成測試中,每次運行測試時都不會發生,並且當它發生時,總是會有不同的測試失敗。另外,如果我只運行剛剛失敗的測試,它們總是會通過。我很難在本地持續重現這一點,但是它在構建服務器上更頻繁地發生,這很痛苦,因爲它阻止構建自動升級到下一個環境。

我也嘗試添加這測試卻一直沒有解決的問題:

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

任何想法?我們有4個不同的人刺傷了這個無濟於事,所以我現在求助於你們偉大的人們尋求幫助。

謝謝!

編輯:

我目前使用初始化被調用該服務的靜態構造函數中的靜態類的配置。 I.E.

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

...

不知道該用它來做什麼還沒有,但它似乎相關。

+0

如何初始化AutoMapper配置(通過配置文件,在應用程序啓動時,IoC等)?你用[AssertConfigurationIsValid](https://github.com/AutoMapper/AutoMapper/wiki/Configuration-validation)檢查你的映射嗎? – Mightymuke

+0

我在問題中添加了一個編輯。是的,我聲稱配置和Im通過該服務的靜態構造函數初始化它。謝謝! –

回答

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方法(沒有足夠詳細的問題,以確定此爲某些)。我不認爲它應該,但希望上面的代碼中至少有一些可能會奇蹟般地爲您解決問題。

+0

感謝您的幫助!我不直接從單元測試調用初始化,但是當單元測試消息提供服務實例時,靜態構造函數將被調用,並且AutoMapperBootstrapper將被觸發。你認爲什麼樣的細節可以提供幫助?我添加了一些我認爲是相關的編輯,但我不知道該怎麼做。謝謝! –

+0

你不應該在服務中初始化AutoMapper,你應該只做一次(例如,在Web應用程序的'Application_Start'中) - 這是我認爲你的單元測試變得小題大做的地方。然後嘗試直接在你的單元測試中調用'ConfigureMappings();'(或者最好初始化你需要的profile/mapping)。 – Mightymuke