Como escrever testes de integração e sistema no Asp.net MVC

Minha aplicação

Eu tenho um design de aplicativo que se parece com isso:

camada de aplicativo da web - aplicativo asp.net MVC com controladores e visualizações que usam POCOs e serviços de chamadacamada de serviço - processos de negócios que usam POCOs e chamam repositórioscamada de dados - repositórios que usam POCOs e se comunicam com o modelo na forma de modelo EF, que faz parte dessa mesma camadaCamada POCO - define todas as classes usadas para intercomunicação entre essas camadas

Portanto, minha camada de dados é completamente transparente para a implementação do modelo de dados, porque a camada superior não usa entidades de dados.

Testando

Por mais que eu entenda a unidade, a integração e o teste do sistema (em relação ao Asp.net MVC) é o seguinte:

teste de unidade - este é fácil. Zombe de objetos dissociados e injete-os em seu teste de unidade para que a unidade testada os useteste de integração - deve criar um grupo de unidades de funcionalidade de produção e zombar do resto: escrevendo testes de integração que testariam a integração de controlador, serviço e repositório sem realmente usar o banco de dados de produçãoteste de sistema - execute testes em todas as camadas sem zombaria, o que significa que também tenho que usar o banco de dados de produção (teste)Problema

Consigo ver facilmente como escrever testes de unidade e de sistema, mas não sei como escrever testes de integração? Talvez minha visão sobre elas esteja completamente distorcida e eu não as entenda.

Como escrever testes de integração e sistema para um aplicativo Asp.net MVC?
Ou qualquer aplicativo .net para esse assunto?

Algum código que ajuda a explicar o problema

Suponha que eu tenha classes como:

TaskController chama paraTaskServiceTaskService chama paraTaskRepositoryTaskRepository manipular dados EF internamente

Então, aqui estão minhas classes (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
    }
    ...
}

O teste de unidade é simples e ficaria assim:

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

    TaskController controller = new TaskController(mock.Object);

    // do the test
}

Mas quando se trata de um teste de integração, como zombamos apenas de certas partes da integração.

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

Antes de tudo, não posso simplesmente zombar do banco de dados aqui? Eu poderia zombar do repositório e ter serviço e controlador reais ...

questionAnswers(3)

yourAnswerToTheQuestion