Cómo escribir pruebas de integración y sistema en Asp.net MVC

Mi aplicación

Tengo un diseño de aplicación que se ve así:

capa de aplicación web: aplicación asp.net MVC con controladores y vistas que utilizan POCO y servicios de llamadascapa de servicio: procesos comerciales que utilizan POCO y depósitos de llamadascapa de datos: repositorios que utilizan POCO y se comunican con el modelo en forma de modelo EF que forma parte de esta misma capaCapa POCO: define todas las clases que se utilizan para la comunicación entre estas capas.

Entonces, mi capa de datos es completamente transparente para la implementación del modelo de datos porque la capa superior no usa entidades de datos en absoluto.

Pruebas

Por mucho que entiendo la unidad, la integración y las pruebas del sistema (en relación con Asp.net MVC) es esto:

pruebas unitarias: esta es fácil. Simula objetos desacoplados e inyéctalos en la prueba de tu unidad para que la unidad probada los useprueba de integración: debe formar un grupo de unidades de funcionalidad de producción y burlarse del resto: escribir pruebas de integración que prueben la integración del controlador, el servicio y el repositorio sin usar realmente la base de datos de producciónprueba del sistema: ejecute pruebas en todas las capas sin ninguna burla, lo que significa que también tengo que usar la base de datos de producción (prueba)Problema

Puedo ver fácilmente cómo escribir pruebas unitarias, así como pruebas de sistema, pero no sé cómo escribir pruebas de integración. Tal vez mi visión de estos está completamente distorsionada y no los entiendo en absoluto.

¿Cómo se deben escribir las pruebas de integración y sistema para una aplicación Asp.net MVC?
¿O alguna aplicación .net para el caso?

Algún código que ayude a explicar el problema.

Supongamos que tengo clases como:

TaskController llamadas aTaskServiceTaskService llamadas aTaskRepositoryTaskRepository manipular datos EF internamente

Así que aquí están mis clases (abreviadas):

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
    }
    ...
}

La prueba unitaria es simple y se vería así:

public void UnitTest()
{
    var mock = new Mock<ITaskService>();
    // other code that mocks the service

    TaskController controller = new TaskController(mock.Object);

    // do the test
}

Pero cuando se trata de una prueba de integración, ¿cómo me burlo solo de ciertas partes de la integración?

public void IntegrationTest()
{
    // no mocking at all
    TaskController = new TaskController();
    // do some testing
}

En primer lugar, ¿no puedo simplemente burlarme de la base de datos aquí? Aunque podría burlarme del repositorio y tener un servicio real y un controlador ...

Respuestas a la pregunta(3)

Su respuesta a la pregunta