gpt4 book ai didi

c# - 对现有 ASP.NET MVC Controller 进行单元测试

转载 作者:行者123 更新时间:2023-12-02 20:46:51 25 4
gpt4 key购买 nike

我阅读了越来越多有关单元测试的内容,并决定将其付诸实践。我挖出了一个使用 ASP.NET MVC 使用存储库模式、依赖注入(inject)和 EF 编写的项目。我的第一个任务是对 Controller 进行单元测试。以下是要测试的 Controller 的片段:

 IUserRepository _userRepository;
IAttachmentRepository _attachmentRepository;
IPeopleRepository _peopleRepository;
ICountryRepository _countryRepository;

public UserController(IUserRepository userRepo, IAttachmentRepository attachRepo, IPeopleRepository peopleRepo, ICountryRepository countryRepo)
{
_userRepository = userRepo;
_attachmentRepository = attachRepo;
_peopleRepository = peopleRepo;
_countryRepository = countryRepo;
}

public ActionResult Details()
{
UserDetailsModel model = new UserDetailsModel();

foreach (var doc in _attachmentRepository.GetPersonAttachments(Globals.UserID))
{
DocumentItemModel item = new DocumentItemModel();
item.AttachmentID = doc.ID;
item.DocumentIcon = AttachmentHelper.GetIconFromFileName(doc.StoragePath);
item.DocumentName = doc.DocumentName;
item.UploadedBy = string.Format("{0} {1}", doc.Forename, doc.Surname);
item.Version = doc.VersionID;

model.Documents.Add(item);
}

var person = _peopleRepository.GetPerson();
var address = _peopleRepository.GetAddress();

model.PersonModel.DateOfBirth = person.DateOfBirth;
model.PersonModel.Forename = person.Forename;
model.PersonModel.Surname = person.Surname;
model.PersonModel.Title = person.Title;

model.AddressModel.AddressLine1 = address.AddressLine1;
model.AddressModel.AddressLine2 = address.AddressLine2;
model.AddressModel.City = address.City;
model.AddressModel.County = address.County;
model.AddressModel.Postcode = address.Postcode;
model.AddressModel.Telephone = address.Telephone;

model.DocumentModel.EntityType = 1;
model.DocumentModel.ID = Globals.UserID;
model.DocumentModel.NewFile = true;

var countries = _countryRepository.GetCountries();

model.AddressModel.Countries = countries.ToSelectListItem(1, c => c.ID, c => c.CountryName, c => c.CountryName, c => c.ID.ToString());

return View(model);
}

我想测试 Details 方法并有以下查询:

1) Globals.UserID 属性从 session 对象中检索当前用户。我如何轻松测试这个(我正在使用内置的 VS2010 单元测试和起订量)

2) 我在这里调用 AttachmentHelper.GetIconFromFileName(),它只是查看文件的扩展名并显示一个图标。我还调用附件存储库中的 GetPersonAttachments,调用 GetPerson、GetAddress 和 GetCountries,以及调用创建的扩展方法,将 List 转换为 SelectListItem 的 IEnumerable。

此 Controller 操作是不良做法的示例吗?它使用大量存储库和其他辅助方法。据我所知,对这个单一操作进行单元测试将需要大量的代码。这会适得其反吗?

在测试项目中对简单 Controller 进行单元测试是一回事,但是当您进入现实生活中的代码时,比如这样,它可能会变成一个怪物。

我想我的问题实际上是我应该重构我的代码以使其更容易测试,还是我的测试应该变得更加复杂以满足当前代码?

最佳答案

复杂的测试和复杂的代码一样糟糕:它们很容易出现错误。因此,为了使测试保持简单,重构应用程序代码以使其更易于测试通常是一个好主意。例如,您应该将 Details() 方法中的映射代码提取到单独的帮助器方法中。然后,您可以非常轻松地测试这些方法,而不必太担心测试 Details() 的所有疯狂组合。

我已经提取了下面的人员和地址映射部分,但您可以将其进一步分解。我只是想让你明白我的意思。

    public ActionResult Details() {
UserDetailsModel model = new UserDetailsModel();

foreach( var doc in _attachmentRepository.GetPersonAttachments( Globals.UserID ) ) {
DocumentItemModel item = new DocumentItemModel();
item.AttachmentID = doc.ID;
item.DocumentIcon = AttachmentHelper.GetIconFromFileName( doc.StoragePath );
item.DocumentName = doc.DocumentName;
item.UploadedBy = string.Format( "{0} {1}", doc.Forename, doc.Surname );
item.Version = doc.VersionID;

model.Documents.Add( item );
}

var person = _peopleRepository.GetPerson();
var address = _peopleRepository.GetAddress();

MapPersonToModel( model, person );

MapAddressToModel( model, address );

model.DocumentModel.EntityType = 1;
model.DocumentModel.ID = Globals.UserID;
model.DocumentModel.NewFile = true;

var countries = _countryRepository.GetCountries();

model.AddressModel.Countries = countries.ToSelectListItem( 1, c => c.ID, c => c.CountryName, c => c.CountryName, c => c.ID.ToString() );

return View( model );
}

public void MapAddressToModel( UserDetailsModel model, Address address ) {
model.AddressModel.AddressLine1 = address.AddressLine1;
model.AddressModel.AddressLine2 = address.AddressLine2;
model.AddressModel.City = address.City;
model.AddressModel.County = address.County;
model.AddressModel.Postcode = address.Postcode;
model.AddressModel.Telephone = address.Telephone;
}

public void MapPersonToModel( UserDetailsModel model, Person person ) {
model.PersonModel.DateOfBirth = person.DateOfBirth;
model.PersonModel.Forename = person.Forename;
model.PersonModel.Surname = person.Surname;
model.PersonModel.Title = person.Title;
}

关于c# - 对现有 ASP.NET MVC Controller 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13871831/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com