I've read more and more about unit testing, and determined to put it to work. I dug out a project which is written with ASP.NET MVC using the repository pattern, dependency injection and EF. My first task was to unit test a controller. Here is a snippet from the controller to test:
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);
}
I want to test the Details method and have the following queries:
1) The Globals.UserID property retrieves the current user from the session object. How can I easily test this (I'm using the built in VS2010 unit testing and Moq)
2) I'm making a call to AttachmentHelper.GetIconFromFileName() here which simply looks at the extension of a file and displays an icon. I'm also making a call to GetPersonAttachments in the attachment repository, a call to GetPerson, GetAddress and GetCountries as well as a call to an extension method created transform a List to IEnumerable of SelectListItem.
Is this controller action an example of bad practice? It's using lots of repositories and also other helper methods. From what I can see, unit testing this single action will require lots and lots of code. Is this counter productive?
Unit testing a simple controller in a test project is one thing, but when you get into real life code such as this it could become a monster.
I guess my question really is should I refactor my code to make it easier to test, or should my tests become much more complex to satisfy the current code?