Как написать интеграционные и системные тесты в Asp.net MVC
У меня есть дизайн приложения, который выглядит так:
уровень веб-приложений - приложение asp.net MVC с контроллерами и представлениями, которые используют POCO и службы вызововуровень обслуживания - бизнес-процессы, использующие POCO и репозитории вызововуровень данных - хранилища, которые используют POCO и связываются с моделью в форме модели EF, которая является частью этого же уровняУровень POCO - определяет все классы, которые используются для взаимодействия между этими уровнямиТаким образом, мой уровень данных полностью прозрачен для реализации модели данных, потому что верхний уровень вообще не использует объекты данных.
тестированиеНасколько я понимаю, юнит, интеграция и тестирование системы (по отношению к Asp.net MVC) таковы:
модульное тестирование - это легко. Смоделируйте разъединенные объекты и внедрите их в свой модульный тест, чтобы протестированный модуль использовал ихИнтеграционное тестирование - должно составить группу функциональных модулей производства и смоделировать остальное: таким образом, написание интеграционных тестов, которые будут тестировать интеграцию контроллера, сервиса и репозитория без фактического использования производственной базы данныхсистемное тестирование - запускать тесты на всех уровнях без каких-либо проверок, а это значит, что я должен использовать и производственную (тестовую) базу данныхпроблемаЯ легко вижу, как писать модульные тесты, а также системные тесты, но я не знаю, как писать интеграционные тесты? Возможно, мой взгляд на них полностью искажен, и я их совсем не понимаю.
Как написать интеграционные и системные тесты для приложения Asp.net MVC?
Или любое приложение .net в этом отношении?
Предположим, у меня есть такие классы, как:
TaskController
призывает вTaskService
TaskService
призывает вTaskRepository
TaskRepository
внутренне манипулировать данными EFИтак, вот мои (сокращенно) классы:
public class TaskController
{
private ITaskService service;
// injection constructor
public TaskController(ITaskService service)
{
this.service = service;
}
// default constructor
public TaskController() : this(new TaskService()) {}
public ActionResult GetTasks()
{
return View(this.service.GetTasks());
}
...
}
public class TaskService : ITaskService
{
private ITaskRepository repository;
// injection constructor
public TaskService(ITaskRepository repository)
{
this.repository = repository;
}
// default constructor
public TaskService() : this(new TaskRepository()) {}
public IList<Task> GetTasks()
{
return this.repository.GetTasks();
}
...
}
public class TaskRepository : ITaskRepository
{
public IList<Task> GetTasks()
{
// code that gets tasks from EF and converts to Task POCOs
}
...
}
Модульный тест прост и будет выглядеть так:
public void UnitTest()
{
var mock = new Mock<ITaskService>();
// other code that mocks the service
TaskController controller = new TaskController(mock.Object);
// do the test
}
Но когда дело доходит до интеграционного теста, как мне высмеивать только определенные части интеграции.
public void IntegrationTest()
{
// no mocking at all
TaskController = new TaskController();
// do some testing
}
Прежде всего, я не могу просто смоделировать базу данных здесь? Я мог бы смоделировать хранилище и иметь реальный сервис и контроллер, хотя ...