Quem deve inicializar dependências em um aplicativo TDD?

8

Estou tentando aprender a implementar o TDD com objetos falsos / zombeteiros. Uma das perguntas que tenho é como inicializar uma dependência em um aplicativo que implementa TDD? Um exemplo deste artigo Iniciando a zombaria com o Moq 3 mostra:

public class OrderWriter
{
    private readonly IFileWriter fileWriter;

    public OrderWriter(IFileWriter fileWriter)
    {
        this.fileWriter = fileWriter;
    }

    public void WriteOrder(Order order)
    {
        fileWriter.WriteLine(String.Format("{0},{1}", order.OrderId, order.OrderTotal));
    }
}

Neste exemplo, o construtor aceita um IFileWriterparâmetro, suponho, porque você deseja fornecer o gravador de arquivo real no caso do aplicativo real e o falso para o teste de unidade. Minha pergunta é, na aplicação real, quem fornecerá esse parâmetro? Suponho que será o chamador desta aplicação. E se também tiver dependência no construtor? O código do chamador também será responsável por isso?

Talvez a melhor maneira seja usar a fábrica. Como esta fábrica funcionaria? E como a fábrica será distribuída? Será no parâmetro construtor como na maneira acima?

Louis Rhys
fonte

Respostas:

7

O que você está procurando é um contêiner de IoC para conectar automaticamente todos os seus objetos na inicialização do aplicativo. Dê uma olhada no Ninject , ele tem um exemplo muito simples na primeira página. (Também é um bom produto e ... bem, ninjas!)

Como regra geral, você deve tentar resolver todos os seus objetos de nível superior (por exemplo, Página no ASP.NET, Controlador no MVC para ASP.NET, Formulário no Winforms) diretamente do contêiner de IoC e deixá-lo conectar TODOS dependências através da injeção do construtor. Haverá momentos em que você precisará forçá-lo a resolver um item de nível inferior - isso é conhecido como usá-lo como um localizador de serviço -, mas isso geralmente deve ser evitado , pois são difíceis (mas não impossíveis) de testar e crie uma API que possa ser confusa para o consumidor, se não for você.

Desde a v3, o ASP.NET para MVC foi projetado especificamente para abstrair o contêiner de IoC do restante do código, permitindo a injeção automática em qualquer classe de nível superior (Controller, View, Filter, etc.) por meio do DependencyResolver classe . Outras estruturas .NET exigem um pouco mais de esforço, mas é possível se você pesquisar no Google.

Há um livro sobre o assunto chamado Injeção de Dependência no .NET . Eu não li pessoalmente, mas ouvi coisas boas.

pdr
fonte
0

Eu já vi a abordagem de adicionar um construtor padrão que chama o construtor parametrizado com instâncias padrão, ou seja, "injeção de dependência do pobre homem".

public OrderWriter()
    : this(new TextFileWriter())
{
}

O caminho do código regular chama o construtor padrão, enquanto o teste de unidade é inicializado usando o construtor personalizado.

Se alguém pudesse elaborar os prós e contras dessa abordagem, eu agradeceria muito.

Timo
fonte