簡體   English   中英

單元測試依賴於AutoMapper和類型轉換器的ASP.NET MVC應用程序服務

[英]Unit testing ASP.NET MVC application services that rely on AutoMapper and type converters

我的ASP.NET MVC 3應用程序的服務層使用AutoMapper將視圖模型映射到業務對象。 我實現了類型轉換器,將發布/獲取請求中提交的對象ID轉換為業務對象。類型轉換器通過ID查找數據庫中的實體,並從中重建業務。 例如:

class UserViewModel {
   // user fields
   Guid? Manager; // this is an ID of another user in the system
}

服務將調用AutoMapper:

var userModel = Mapper.Map<UserViewModel, UserModel>(viewModel);

映射到此類:

class UserModel {
    // other fields...
    UserModel Manager;
}

借助類型轉換器的幫助,該類型轉換器通過Manager GUID從視圖模型中查找數據庫中的另一個用戶。 使用Ninject向類型轉換器注入依賴項,並且在Web應用程序中一切正常。

我正在嘗試編寫將使用模擬存儲庫和類型轉換器的單元測試。 可以將AutoMapper配置為使用用戶提供的功能來構造服務:

Mapper.Initialize(cfg =>
{
    cfg.ConstructServicesUsing(type => Kernel.GetService(type));
});

在Web應用程序中,內核是Ninject,對於測試,我決定提供自己的方法,該方法從字典中返回請求的類型的實例:

Dictionary<Type, object> typeDict = new Dictionary<Type, object>()
{
    { typeof(IRepository), new MockRepository() }
};

...
Mapper.Initialize(cfg =>
{
    cfg.ConstructServicesUsing(type => { return typeDict[type]; } );
});

這個想法是,當將AutoMapper配置為將Guid轉換為這樣的對象時:

Mapper.CreateMap<Guid?, TDropDown>()
       .ConvertUsing<GuidToSelectListValueConverter<TDropDown>>();

並且需要創建一個GuidToSelectListValueConverter的新實例,並向其注入存儲庫,它將使用ConstructServicesUsing中配置的方法請求IRepository類型。

相反,AutoMapper實際上嘗試獲取GuidToSelectListValueConverter類型的實例。 這意味着我要負責創建類型轉換器的新實例並將其注入依賴項。 我的typeDict應該看起來像這樣:

Dictionary<Type, object> typeDict = new Dictionary<Type, object>()
{
    { typeof(GuidToSelectListValueConverter), new GuidToSelectListValueConverter(
               new MockRepository()) }
};

我確實有很多類型轉換器,並且為那些似乎不可行的手動編寫解析器功能。 所以這讓我開始思考。 簡單地配置Ninject來解決我的單元測試中的這些依賴關系是否會出錯? 我可以將IRepository綁定到MockRepository,然后當我需要服務實例時,只需調用Kernel.GetService(typeof(MyService))並讓Ninject用MockRepository注入它。 額外的好處是AutoMapper還將使用Ninject獲取類型轉換器和值解析器的實例:

// configure Ninject
Kernel.Bind<IRepository>().To<MockRepository>();
// initialize AutoMapper
Mapper.Initialize(cfg => 
{ 
    cfg.ConstructServicesUsing(t => Kernel.GetService(t)); 
});
// create an instance of service to test
var service = Kernel.GetService(IMyService);
// do work
var result = service.DoWork();
// analyze result

現在,當DoWork方法調用Mapper.Map時,將使用Ninject創建類型轉換器。

歡迎任何建議,想法和最佳實踐建議。

謝謝!

查看有關將IoC與AutoMapper結合使用的信息

通過在控制器中使用IMappingEngine而不是Mapper ,這有助於我朝正確的方向前進。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM