Следующая строка убивает все и вводит невозможное для модульного тестирования изолированное прочное соединение между вашим контроллером и уровнем доступа к данным:
IUserRepository repo = new UserRepository();
Абсолютно никогда не пишите ничего подобного в любом приложении (не только в ASP.NET MVC). если вы напишите такой код, он всегда будет прерываться в вашем модульном тесте, и вы не сможете его протестировать.
Нельзя издеваться / юнит-тест.
Вы должны использовать инжектор конструктора, чтобы ослабить связь между вашими слоями:
public class UserController : Controller{
private readonly IUserRepository _repos;
public UserController(IUserRepository repo)
{
_repos = repo;
}
public ActionResult Index()
{
return RedirectToAction("Details");
}
public ActionResult Details()
{
IQueryable<Business.Entities.User> users = _repos.GetAll();
return View("Details", users);
}}
Теперь вы можете выполнить модульное тестирование изолированно, издеваясь:
[Test]
public void Details()
{
Mock<IUserRepository> mockRepo = new Mock<IUserRepository>();
mockRepo.Setup(ur => ur.GetAll()).Returns(MockedGetAll());
var v = mockRepo.Object.GetAll();
var controller = new UserController(mockRepo.Object);
var result = controller.List() as ViewResult;
var model = result.ViewData.Model as IQueryable<User>;
Assert.AreEqual("List", result.ViewName);
Assert.IsNotNull(model);
Assert.Greater(model.Count(), 0);}
Очевидно, что теперь, когда ваш контроллер зависит от этого хранилища, вы можете использовать инфраструктуру DI для настройки ваших зависимостей.
Люди, которые не хотят использовать DI-фреймворк, часто пишут такой код и предоставляют 2 конструктора (один для модульного тестирования и один для реального приложения):
private readonly IUserRepository _repo;
public UserController(IUserRepository repo)
{
_repo = repo;
}
public UserController(): this(new UserRepository())
{}
См. Также
религия внедрения зависимости