Code Snippet para TestMethods no VisualStudio

Filed Under (.NET, Boas Práticas, TDD, Visual Studio 2010) by Vinicius Quaiato on 09-03-2010

Tagged Under : ,

Sempre achei um “pé” ter que ficar copiando métodos de teste, tudo pela preguiça de colocar o attribute [TestMethod] public void etc, etc.

Criei um CodeSnippet pra ser usado com C# que resolve alguns desses problemas. Abaixo segue o código do Snippet, à noite eu mostro como inserir o mesmo no VisualStudio, e coloco um link para download também:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2010/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Test Method</Title>
      <Shortcut>test</Shortcut>
      <Description>Code snippet to create a test method</Description>
      <Author>Vinicius Quaiato</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>Test_Method_Name</ID>
          <ToolTip>The name of the method. Try using a name that indicates the purpose of the test</ToolTip>
          <Default>Test_Method_Name</Default>
       </Literal>
     </Declarations>
     <Code Language="csharp">
       <![CDATA[	[TestMethod]
	public void $Test_Method_Name$()
	{   
 
	}]]>
     </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Espero que ajude um pouco. É mais rápido digitar “test + tab + tab” do que copiar, colar e alterar o nome do método anterior.

Abraços,
Vinicius Quaiato.

Dojo .Net Architects: Vídeo e Apresentação

Filed Under (.NET, Boas Práticas, Dojos, Publicações, TDD) by Vinicius Quaiato on 27-02-2010

Tagged Under : , ,

Fala galera. Abaixo está o vídeo e apresentação do Coding Dojo do .Net Architects.

Apresentação:

Vídeo do Dojo:

Mais detalhes podem ser vistos aqui:
http://dojo.dotnetarchitects.net/index.php/2010/02/27/resultado-1-coding-dojo-net-architects/

Abraços,
Vinicius Quaiato.

Coding Dojo .NET Architects – 30/01/2010 – São Paulo

Filed Under (.NET, Boas Práticas, Dojos, TDD) by Vinicius Quaiato on 29-01-2010

Tagged Under : , ,

Fala galera! Sábado, dia 30/01/2010 teremos um Coding Dojo, organizado pela comunidade .NET Architects.

Este Coding Dojo dará início ao grupo de Dojo do .NET Architects, que fará encontros regulares focando os dojos nas diversas linguagens e tecnologias .NET.

Local: Unip Jaguaré – São Paulo – SP
Horário: à partir das 10hs
Data: sábado, 30/01/2010

Confira o mapa do local e faça sua incrição aqui: http://dojo.dotnetarchitects.net
Totalmente gratuito!

Não existem pré-requisitos para participar, basta ter vontade e comparecer!

Saiba mais sobre Coding Dojo aqui.

Abraços, nos vemos lá!

Vinicius Quaiato.

Entity Framework 4 – Model First com POCOs

Filed Under (.NET, .NET 4.0, Boas Práticas, Entity Framework, Visual Studio 2010) by Vinicius Quaiato on 27-01-2010

Tagged Under : , ,

Fala galera, de buenas? Resolvi escrever um pouco sobre o Entity Framework 4.0 (na verdade é a versão 2 do EF mas para acompanhar o .NET 4.0 ele será chamado assim também).

Hoje vou mostrar uma característica bem interessante, que é o model first trabalhando com POCOs.
Model First diz respeito a primeiro criar suas entidades, ou seja, suas classes, e somente depois modelar o banco de dados – e é isto que queremos fazer quando desenvolvemos aplicações usando Orientação a Objetos, não é?
POCOs são classes simples, que não herdam nem implementam nenhuma outra classes/interface específica de frameworks, dizendo respeito exclusivamente ao nosso domínio e contendo apenas o necessário ao nosso domínio.

Para começar vamos criar um projeto de testes e adicionar um arquivo .edmx como mostra a figura abaixo:



Feito isso vamos selecionar o tipo de modelo “empty model”:

Selecionando o empty model

Selecionando o empty model


Pronto!
Vamos então adicionar duas entidades ao nosso design surface. Estas serão nossas entidades POCO, ou seja, não terão nenhuma dependência do Entity Framework, nem do Linq, nem de nada, é apenas o nosso modelo de classes, vamos ainda desabilitar a geração de código do Visual Studio, para que ele não “polua” as classes:


E então clicamos na parte branca do design e abrimos a janela de propriedades para desabilitar a geração de código:


Estamos a meio caminho andado. Pode parecer muito trabalho a ser feito, mas isso não leva mais do que 2 minutos. É realmente simples e os resultados são muito bons.
Agora vamos para a parte bacana, codificar nossas classes.
Vamos iniciar codificando as classes Pedido e ItemPedido, que são classes realmente bastante simples:

public class Pedido
{
    public virtual int Id { get; set; }
    private IList<ItemPedido> itens = new List<ItemPedido>();
    public virtual IList<ItemPedido> Itens
    {
        get { return this.itens; }
        set { this.itens = value; }
    }
}
 
public class ItemPedido
{
    public virtual int Id { get; set; }
    public virtual string Produto { get; set; }
    public virtual int Quantidade { get; set; }
    public virtual Pedido Pedido { get; set; }
}

Os virtuais que usamos nas nossas classes são para que o Entity Framework possa fazer o “tracking” dos nossos objetos. Internamente ele criará proxies para nossas classes. Em um primeiro momento basta colocarmos as propriedades como virtual e ele se encarregará de tudo, isso ainda ajudará no Lazy Loading.

Agora, como desabilitamos a geração de código, precisamos também criar o nosso contexto do EF. Isso é bastante simples, e neste cenário nos obrigará a escrever apenas umas 10 linhas de código, como pode ser visto abaixo:

public class EF4Context : ObjectContext
{
    public EF4Context()
        : base("name=EF4Container", "EF4Container") { }
 
    private IObjectSet<Pedido> pedidos;
    public IObjectSet<Pedido> Pedidos
    {
        get
        {
            if (pedidos == null)
                pedidos = CreateObjectSet<Pedido>();
 
            return pedidos;
        }
    }
}

Feito isso nos resta apenas gerar o banco de dados. Como dissemos, geramos primeiro nossas classes, sem nos preocupar em como estes dados seriam armazenados, conseguimos focar puramente no nosso domínio e no nosso modelo, afinal estamos pensando em classes e objetos, e não em linhas/tuplas de banco, chaves, índices, etc.
O Visual Studio irá gerar o código necessário para nosso banco de dados veja abaixo:


Agora é só executar o SQL gerado:


Se vocês fizeram tudo certinho até o momento, devem ser capazes de executar os seguintes códigos de testes com sucesso:

[TestMethod]
public void Deve_Adicionar_Um_Pedido_No_DB_Usando_Contexto_E_Poco()
{
    var contexto = new EF4Context();
 
    var pedido = new Pedido();
 
    pedido.Itens.Add(new ItemPedido
    {
        Produto = "Novo Produto",
        Quantidade = 5,
        Pedido = pedido
    });
 
    contexto.AddObject("PedidoSet", pedido);
    contexto.SaveChanges();
}

Depois este:

[TestMethod]
public void Deve_Obter_Todos_Os_Pedidos_Do_Banco_Usando_Contexto_E_Pocos()
{
    var contexto = new EF4Context();
 
    var pedidos = contexto.Pedidos.ToList();
 
    Assert.IsTrue(pedidos.Count > 0);
}

E por fim este:

1
2
3
4
5
6
7
8
9
10
11
12
13
[TestMethod]
public void Deve_Selecionar_1_Pedido_Do_Banco_Usando_Contexto_E_Pocos()
{
    var contexto = new EF4Context();
    contexto.ContextOptions.LazyLoadingEnabled = true;
 
    var pedido = contexto.Pedidos
                            .Where(p => p.Id == 1).Single();
 
    Assert.AreEqual(1, pedido.Id);
    Assert.IsTrue(pedido.Itens.Count > 0);
    Assert.AreEqual("Novo Produto", pedido.Itens[0].Produto);
}

Percebam como na linha 5 habilitamos o lazy loading para que as propriedades sejam carregadas no momento em que forem chamadas apenas.

E se fizermos uma consulta no banco de dados, veremos que de fato os dados estão lá:


Bom pessoal, é isso.
Esta é uma das funcionalidades presentes no Entity Framework 4.0. É claro que existe muita coisa a ser explorada ainda, e existem muitas coisas a serem feitas ainda, mas é um enorme avanço poder trabalhar com POCOs e utilizar os recursos de uma ferrmenta ORM como o EF. Poder dar “tchau” para os SqlConnection, SqlCommand, ExecuteScalar, etc, é algo realmente incrível.

Espero que tenham gostado. Dúvidas, críticas e sugestões me enviem email ou comentários.

Abraços,
Vinicius Quaiato.

Injeção de Dependência com MS Unity

Filed Under (.NET, Boas Práticas, Patterns) by Vinicius Quaiato on 18-01-2010

Tagged Under : , , , ,

Bom pessoal, pudemos ver os benefícios e alguns usos de Inversão de Controle e Injeção de Dependências aqui e aqui.

Uma das formas de obter excelentes ganhos com a inversão de controle é através da utilização de um contêiner de Injeção de Dependências.

Um contêiner de injeção de dependências é capaz de criar objetos com todas suas dependências injetadas e totalmente pronto para uso. Em geral estes conteiners podem ser configurados manualmente(programaticamente) ou dinamicamente(através de arquivos de configuração por exemplo).

Falaremos um pouco do Unity que é um contêiner de Injeção de Dependência que faz parte dos Application Blocks da Microsoft.

Para que vejamos como o Unity funciona faça o download do mesmo aqui e execute o setup, que irá apenas criar uma pasta com as DLLs do Unity.

O Unity, como veremos nos exemplos, suporta 3 tipos de injeção de dependência:

  • Constructor Injection (injeção por construtor)
  • Property Injection (injeção de propriedade)
  • Method Call Injection (injeção de chamada de métodos)

Vamos usar como exemplo estas classes e interfaces:

public interface ILogger
{
    void RegistrarMensagem(string mensagem);
}
 
public class SqlLogger : ILogger
{
    public void RegistrarMensagem(string mensagem)
    {
        //abre conexão SQL
 
        //Executa insert da mensagem
    }
}
 
public class EnviadorDeEmails
{
    public ILogger Logger { get; set; }
    public EnviadorDeEmails(ILogger logger)
    {
        this.Logger = logger;
    }
    public void EnviarEmail(string email, string mensagem)
    {
        //Envia email
 
        //registra envio
        this.Logger.RegistrarMensagem(string.Format("Email enviado para {0}", email));
    }
}

Adicione as seguintes referências ao seu projeto: Microsoft.Practices.ObjectBuilder2.dll e Microsoft.Practices.Unity.dll que se encontram na pasta que você “instalou” o Unity, como pode ser visto na figura abaixo:
Incluindo Dlls do Unity

As classes acima são bem simples, no final das contas o que faremos é com que o Unity crie um EnviadorDeEmails com a dependência de ILogger injetada e resolvida, ou seja, que ele crie um EnviadorDeEmails passando para ele um SqlLogger. Para isso vamos “ensinar” ao Unity como resolver a interface ILogger, como pode ser visto no código abaixo:

1
2
    var unityContainer = new UnityContainer();
    unityContainer.RegisterType<ILogger, SqlLogger>();

Na linha 1 criamos uma instância do contêiner do Unity. Na linha 2 dizemos para o Unity que quando quisermos o tipo ILogger (interface) ele deve utilizar a classe concreta SqlLogger. Simples assim.

Constructor Injection

Agora podemos mandar que o Unity construa nosso EnviadorDeEmails usando constructor injection, conforme visto abaixo:

1
2
3
4
5
6
7
8
9
10
[TestMethod]
public void Configurando_Unity_Para_Resolver_ILogger()
{
    var unityContainer = new UnityContainer();
    unityContainer.RegisterType<ILogger, SqlLogger>();
 
    var enviadorEmails = unityContainer.Resolve<EnviadorDeEmails>();
 
    Assert.IsInstanceOfType(enviadorEmails.Logger, typeof(SqlLogger));
}

O grande segredo aí está na linha 7 onde dizemos para o Unity construir nosso EnviadorDeEmails. O Unity percebe que existe uma dependência no construtor do EnviadorDeEmails, e baseado na configuração que fizemos ele sabe como resolver esta dependência. Na linha 9 apenas verificamos se de fato o ILogger utilizado é o SqlLogger, e executando o teste obtemos sucesso.
E notem que neste caso utilizamos o constructor injection pois a classe EnviadorDeEmails possui um construtor com uma dependência para uma interface, que o Unity conhece.

Property Injection

Poderíamos dizer que a dependência não deve ser resolvida via construtor, mas sim diretamente na propriedade, para isso alteraríamos a classe EnviadorDeEmails assim:

1
2
3
4
5
6
7
8
9
10
11
12
public class EnviadorDeEmails
{
    [Dependency]
    public ILogger Logger { get; set; }
    public void EnviarEmail(string email, string mensagem)
    {
        //Envia email
 
        //registra envio
        this.Logger.RegistrarMensagem(string.Format("Email enviado para {0}", email));
    }
}

A única diferença aqui foi a utilização do DependencyAttribute na linha 3 para marcar que a propriedade Logger, do tipo ILogger, deve ser resolvida pelo Unity.
Executando nosso teste mais uma vez devemos obter sucesso.

Method Call Injection

A outra forma que o Unity tem para injetar nossas dependências é através da chamada de um método. Por exemplo, imaginem que temos um método Initialize na nossa classe, que é responsável por criar os objetos que nossa classe precisa. Podemos fazer com que o Unity execute este método resolvendo todas as dependências.
Vejamos o código da classe EnviadorDeEmails utilizando um Method Call Injection:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class EnviadorDeEmails
{
    public ILogger Logger { get; set; }
    public void EnviarEmail(string email, string mensagem)
    {
        //Envia email
 
        //registra envio
        this.Logger.RegistrarMensagem(string.Format("Email enviado para {0}", email));
    }
 
    [InjectionMethod]
    public void Inicializador(ILogger logger)
    {
        this.Logger = logger;
    }
}

Tudo o que fizemos desta vez foi criar um método, neste caso o método Inicializador, na linha 13, que recebe como parâmetros as dependências da nossa classe. E marcamos este método com o InjectionMethodAttribute, para dizer ao Unity que este método deve ser chamado e resolvidor por ele na criação de nosso EnviadorDeEmails.
E novamente se executarmos o mesmo método de teste, obteremos sucesso.

Como vimos nos três exemplos acima, o Unity após configurado consegue resolver as dependências de nossas classes de forma simples e trivial. Basta alterarmos a forma de resolução da dependência, por exemplo de constructor para setter, e nada no código mudará, assim como se mudar de SqlLogger para XmlLogger, nada no código mudará, apenas a configuração do Unity.

Bom galera, é mais ou menos isso. O Unity é uma ferramenta bastante poderosa, extensível e simples de usar.

Qualquer dúvida é só escrever nos comentários ou enviar email.

Abraços,
Vinicius Quaiato.

TDD na .Net Magazine 69

Filed Under (.NET, Boas Práticas, Publicações, TDD) by Vinicius Quaiato on 07-01-2010

Tagged Under : , ,

.NET Magazine edição 69

Acaba de chegar às bancas a .NET Magazine com um artigo sobre TDD.

Neste artigo eu demonstro passo-a-passo a utilização do TDD na criação de uma simples aplicação de compras.

Vários dos benefícios do TDD são demonstrados na prática.

O link para a matéria online é:
http://www.devmedia.com.br/articles/viewcomp.asp?comp=15242

Série de posts sobre TDD aqui no blog:
http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c/

http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-ii/

http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-iii/

http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-iv/

É isso aê galera, boa leitura e dêem seu feedback!

Abraços, Vinicius Quaiato.

Injeção de Dependência no C#

Filed Under (.NET, Boas Práticas, Patterns) by Vinicius Quaiato on 21-12-2009

Tagged Under : , , , , ,

Hoje vamos falar um pouco sobre Injeção de Dependências no C#.

Injeção de Dependência é uma das formas de obter Inversão de Controle.

O nome já diz quase tudo, quando uma classe possui dependência de alguma outra classe concreta, devemos então criar uma dependência para uma interface, ou seja, uma abstração.
Com nossa classe dependendo de uma abstração, nós injetamos um objeto concreto nela.

É um conceito bastante simples, vamos entender com um pouco de código.

A classe abaixo é uma classe de acesso ao banco de dados. Ela é responsável por executar um comando SQL apenas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class SqlClass
{
    public void ExecutarComando(string comando)
    {
        try
        {
            using (SqlConnection conexao = new SqlConnection("CONNECTION STRING"))
            {
                using (SqlCommand comandoSql = conexao.CreateCommand())
                {
                    comandoSql.CommandText = comando;
                    comandoSql.CommandType = CommandType.Text;
 
                    comandoSql.ExecuteNonQuery();
                }
            }
        }
        catch (SqlException sqlEx)
        {
            new LogErros().RegistrarArquivoTexto(sqlEx.Message);
 
            throw sqlEx;
        }
    }
}

Qual o problema desta classe? Simples, ela depende de uma classe concreta de log, como pode ser visto na linha 20.

O que podemos fazer para resolver este problema?
Em primeiro lugar precisamos extrair uma interface para a geração de logs, teríamos uma interface mais ou menos assim:

public interface ILogErros
{
    void RegistrarErro(string mensagemDeErro);
}

Agora fazemos nossa classe de banco de dados conhecer esta interface e criar uma forma de ter um objeto que implemente esta interface injetado:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class SqlClass
{
    private ILogErros logErros = null;
 
    public SqlClass(ILogErros objetoLog)
    {
        this.logErros = objetoLog;
    }
 
    public void ExecutarComando(string comando)
    {
        try
        {
            using (SqlConnection conexao = new SqlConnection("CONNECTION STRING"))
            {
                using (SqlCommand comandoSql = conexao.CreateCommand())
                {
                    comandoSql.CommandText = comando;
                    comandoSql.CommandType = CommandType.Text;
 
                    comandoSql.ExecuteNonQuery();
                }
            }
        }
        catch (SqlException sqlEx)
        {
            logErros.RegistrarErro(sqlEx.Message);
 
            throw sqlEx;
        }
    }
}

Na linha 3 criamos um campo na classe do tipo da interface. É importante perceber que agora nossa classe de banco de dados não conhece o objeto de log, ela apenas conhece sua interface. Ela não sabe como o log será gravado.
Nas linhas 5 a 8 criamos um construtor que recebe um objeto que implementa a interface ILogErros, e este construtor irá garantir que quem quer que instancie a classe tenha que injetar um objeto de log para ela. E isto é Injeção de Dependências!

Este tipo de injeção de dependência é conhecido como Constructor Injection, ou seja, injeção via construtor.

Agora para que consigamos instanciar nossa classe SqlClass precisamos passar um objeto que implemente ILogErros, algo mais ou menos assim:

SqlClass sql = new SqlClass(new LogEmArquivoTexto());

Onde LogEmArquivoTexto implementa ILogErros.

Podemos usar o recurso de Inversão de Controle visto aqui para criarmos uma factory que já nos retorne um objeto SqlClass com a dependência injetada, nos poupando algum trabalho.

E no próximo post veremos como utilizar o Unity, um contêiner de injeção de dependências da Microsoft.

Abraços galera, espero que tenham gostado.
Qualquer dúvida é só escrever.

Att,
Vinicius Quaiato.

Inversão de Controle (Inversion of Control / IoC)

Filed Under (.NET, Boas Práticas, Patterns) by Vinicius Quaiato on 09-12-2009

Tagged Under : , , , , ,

Fala galera, beleza?
Escolhi falar de Inversão de Controle pois recentemente precisei utilizar este conceito em uma nova implementação no trabalho. E também percebi o quão necessário é que os desenvolvedores conheçam este conceito/padrão/técnica.

Bom vamos lá.
Inversão de Controle, como o próprio nome diz significa que o controle de execução do programa/código muda. Eu gosto de pensar também que o controle de conhecimento do código muda.

Como isso?
De uma forma bem simplista podemos dizer por exemplo que o controle que uma classe/método possui acaba sendo mudado, invertido, para algum outro ponto do código.

Vamos ver um exemplo de código:

1
2
3
4
5
6
7
8
9
10
11
12
public class Pedido
{
    private EnviadorDeEmails enviador = null;
 
    public void Gravar()
    {
        //Vai ao banco de dados
 
        this.enviador = new EnviadorDeEmails("smtp","conta@empresa.com","senha");
        this.enviador.EnviarEmail("Novo Pedido Criado!");
    }
}

Esta classe possui não somente o controle do fluxo de execução do programa, mas ela possui o controle sobre o código, e isso significa alto acoplamento e responsabilidades demais.
Ela sabe exatamente como criar um EnviadorDeEmails, e controla também os parâmetros de configuração do smtp.
Ainda que ela recuperasse estes valores do arquivo .config ou do banco de dados, ela teria esse controle.

Como poderíamos, de forma simples, inverter este controle? Uma maneira simples e eficaz seria utilizando um Factory Method estático, na própria classe EnviadorDeEmails, vejamos como ficaria:

1
2
3
4
5
6
7
8
public static EnviadorDeEmails ObterEnviadorDeEmails()
{
    //valores podem vir do .config
    //podem vir do banco
    //quem consome esta classe não sabe
    //ela não tem controle sobre isso
    return new EnviadorDeEmails("smtp", "email@empresa.com", "senha");
}

E então nossa classe Pedido ficaria assim:

1
2
3
4
5
6
7
8
9
10
11
12
public class Pedido
{
    private EnviadorDeEmails enviador = null;
 
    public void Gravar()
    {
        //Vai ao banco de dados
 
        this.enviador = EnviadorDeEmails.ObterEnviadorDeEmails();
        this.enviador.EnviarEmail("Novo Pedido Criado!");
    }
}

É isso pessoal.
Esta é uma das muitas maneiras de realizar Inversão de Controle.
Como Martin Fowler explica, uma outra forma de IoC seria utilizando Template Methods. A classe abstrata define o fluxo de controle, mas o que será executado é o código cliente quem define, e assim o controle é novamente invertido.

Poderíamos fazer isso utilizando Injeção de Dependências, e Contêiners de IoC/DI.
Nos próximos posts falaremos mais sobre Injeção de Dependências e Contêiners de IoC.

Martin Fowler tem um texto clássico sobre este assunto: http://martinfowler.com/bliki/InversionOfControl.html

Abraços.
Vinicius Quaiato.

Podcast Princípios SOLID – .NET Architects

Filed Under (.NET, Boas Práticas, Patterns, Podcasts) by Vinicius Quaiato on 24-11-2009

Tagged Under : , ,

Fala galera, beleza?

Bom, semana passada fiz a gravação de um Podcast com 2 grandes arquitetos de software membros da comunidade .NET Architects, o Giovanni Bassi e o Alexandre Valente.

O tema do podcast foi: Princípios S.O.L.I.D, princípios de design de aplicações Orientadas a Objetos.

Para baixar e/ou ouvir o Podcast:
http://podcast.dotnetarchitects.net/2009/11/podcast-8-principios-s-o-l-i-d/

Para saber mais sobre solid:
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

Para participar do grupo de discussões .Net Architects online:
http://groups.google.com/group/dotnetarchitects

Espero que gostem, em breve teremos mais.

Abraços,
Vinicius Quaiato.

TDD – Test-driven Development + c# + Mocks – Parte IV

Filed Under (.NET, Boas Práticas, TDD) by Vinicius Quaiato on 09-11-2009

Tagged Under : , , ,

Fala galera, beleza?

Dando continuidade a nossa série de artigos sobre TDD, vamos hoje falar de um ponto muito interessante: Mocks.

Artigos anteriores:

Parte I – http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c/
Parte II – http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-ii/
Parte III – http://viniciusquaiato.com/blog/index.php/tdd-test-driven-development-c-parte-iii/

De uma maneira resumida mocks são objetos que simulam o comportamento de outros objetos. Desta forma quando testamos com mocks geralmente testamos o comportamento entre os objetos e não os seus estados.

Utilizar mocks é algo muito interessante, pois eles nos permitem realizar testes com objetos “de mentira” ao invés de objetos que temos implementados como bancos de dados, serviços, web services, por exemplo. Ou seja, conseguimos verificar o comportamente de nossos objetos de negócios quando relacionados com objetos/ações que não temos o controle para testar (por exemplo uma ida ao web service), ou que são muito pesadas para colocar em unit testes automatizados (idas ao banco, chamadas a um webservice, envios de e-mail, etc).

Vamos continuar nosso exemplo das contas bancárias, e imaginar que a cada operação se depósito realizada é necessário utilizar um webservice do banco para registrar um log da ação.

Não vou abordar a criação do Web Service, e de fato nem vou utilizar um, vamos apenas definir que ele implementa a seguinte interface que recebe uma string com o nome da operação e o valor:

public interface IWebServiceContas
{
    string RegistrarOperacaoEmConta(string nomeOperacao, decimal valorOperacao);
}

Para trabalhar com mocks neste post utilizarei o framework Moq(lê-se Mock you), que pode ser baixado aqui: http://code.google.com/p/moq/

Para que possamos adicionar este comportamento às nossas contas(fazer chamada ao webservice), precisaremos alterar o código que já funciona, desta forma os testes que já existem nos ajudarão a saber se algo novo quebrou algo que já estava funcionando.
Vamos começar criando um teste de depósito que deverá fazer uma chamada para o webservice:

[TestMethod]
public void Deve_Realizar_Deposito_10_E_Chamar_WebService()
{
    var conta = new ContaBancaria(10);
    conta.Depositar(10);
}

Este teste por enquanto só está realizando o depósito, precisamos então garantir que o webservice seja chamado, e é utilizando um mock que faremos isso.
Adicione a dll do Moq ao seu projeto:

Adicionar Dll Moq

Adicionar Dll Moq

Agora vamos criar nosso primeiro mock e também incluir a referência na classe de testes:

using Moq;

e

[TestMethod]
public void Deve_Realizar_Deposito_10_E_Chamar_WebService()
{
    var mockWebService = new Mock<IWebServiceContas>();
 
    var conta = new ContaBancaria(10);
    conta.Depositar(10);
}

Podemos perceber que, agora, estamos com um problema. Nossa classe de contas não possui uma instância de IWebServiceContas, e não me parece uma boa solução passar esta instância para o método Depositar. Sendo assim, vamos deixar este teste “pausado” por enquanto.
Para fazermos isso basta colocarmos o Attribute [Ignore] antes do teste e ele não será executado:

[Ignore]
[TestMethod]
public void Este_Teste_Esta_Ignorado() { //teste ignorado }

Vamos alterar nossos testes para que garantam que a nossa conta receba uma instância de IWebServiceContas(injeção de dependância) no seu construtor, para isso vamos alterar nosso primeiro teste bem como o seu nome (lembrem, os testes devem evoluir junto com o código e com o modelo do domínio):

[TestMethod]
public void Deve_Criar_Conta_Com_Deposito_Inicial_E_InstanciaWebService()
{
    Mock mockWebService = new Mock<IWebServiceContas>();
 
    ContaBancaria conta = new ContaBancaria(50, mockWebService.Object);
 
    Assert.AreEqual(50, conta.SaldoAtual);
}

Ok, agora nada compila. Perfeito! Vamos alterar nossa classe para que ela receba um objeto que implemente IWebServiceContas:

public ContaBancaria(decimal depositoInicial, IWebServiceContas webservice)
{
    Validar(depositoInicial);
 
    this.SaldoAtual += depositoInicial;
}

Comos todos os nossos testes criam instâncias de contas, vamos atualizá-los para que compilem e então vamos executar todos os testes:

Executando todos os testes

Executando todos os testes

Agora podemos voltar ao teste que estávamos escrevendo, afinal nossa alteração não quebrou nada.
Para que configuremos nosso mock para atuar como o webservice precisamos fazer seu setup (linhas 5 e 6), e depois verificamos se tudo ocorreu como esperado (linha 11):

[TestMethod]
public void Deve_Realizar_Deposito_10_E_Chamar_WebService()
{
    var mockWebService = new Mock<IWebServiceContas>();
    mockWebService
        .Setup(ws => ws.RegistrarOperacaoEmConta("Depósito", 10));
 
    var conta = new ContaBancaria(10, mockWebService.Object);
    conta.Depositar(10);
 
    mockWebService.VerifyAll();
}

O que fizemos nas linhas 5 e 6 foi dizer ao mock “hey mock! Espero que o método RegistrarOperacaoEmConta seja chamado com os argumentos “Depósito” e 10″.
Depois na linha 11 dizemos para ele “hey! Verifique se tudo o que eu configurei aconteceu aê!”.
Desta forma nosso mock se comporta como se fosse o webservice, ele está imitando o comportamento do webservice através de sua interface IWebServiceContas, com a enorme vantagem de que temos total controle sobre o mock e não estamos dependentes do webservice e nem de uma implementação concreta para testar.

Se rodarmos nossos testes teremos:

Executand teste com Mock do Moq

Executand teste com Mock do Moq

É bem simples o que aconteceu, configuramos nosso mock dizendo que o método RegistrarOperacaoEmConta seria chamado, no entanto esse método não foi chamado. Para isso precisamos alterar nossa classe conta, para que de fato ela chame o método do webservice (ou melhor, do objeto que implementa a interface do webservice).
Porém quando passamos o parâmetro no construtor da nossa classe de ContaBancaria não armazenamos este objeto em um campo da classe. Vamos então criar uma propriedade privada deste tipo na classe conta bancária(linhas 5 e 9):

public class ContaBancaria
{
    //outros membros da classe
 
    private IWebServiceContas webServiceContas = null;
 
    public ContaBancaria(decimal depositoInicial, IWebServiceContas webservice)
    {
        this.webServiceContas = webservice;
 
        Validar(depositoInicial);
 
        this.SaldoAtual += depositoInicial;
    }
//continuação da classe

Agora que fizemos uma alteração, vamos rodar todos os testes e ver se tudo está ok. O resultado deve ser de que tudo está funcionando perfeitamente.

Agora vamos retomar a alteração do método Depositar para que ele passe no teste do mock:

public void Depositar(decimal valorDoDeposito)
{
    this.SaldoAtual += valorDoDeposito;
 
    this.webServiceContas.RegistrarOperacaoEmConta("Depósito", 10);
}

E quando rodamos os testes obtivemos vários erros:

Rodando Teste Mock

Rodando Teste Mock

Isso ocorreu pois eu alterei meus testes passando null para o parâmetro do IWebServiceContas, desta forma vou acrescentar uma validação extra ao meu construtor, garantindo que o serviço esteja presente na construção da conta (vamos imaginar que é uma regra):

[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void Deve_Lancar_Excecao_Deposito_Inicial_Valido_E_Servico_Nulo()
{
    ContaBancaria conta = new ContaBancaria(10, null);
}

E agora altero o construtor para respeitar a regra:

public ContaBancaria(decimal depositoInicial, IWebServiceContas webservice)
{
    Validar(depositoInicial);
    Validar(webservice);
 
    this.webServiceContas = webservice;
    this.SaldoAtual += depositoInicial;
}
 
private void Validar(IWebServiceContas webservice)
{
    if (webservice == null)
        throw new ArgumentException("Serviço de Contas não pode ser nulo!");
}

E rodando os testes vamos ver que só falharam os lugares onde eu mantive o construtor passando null, ou seja, sem respeitar a regra, desta forma vou atualizar os testes para respeitar.

Agora vou executar novamente todos os testes e ver o que aconteceu:

Rodando Todos Testes e Teste Mock

Rodando Todos Testes e Teste Mock

Pronto agora podemos ver que até mesmo nosso teste com o mock está funcionando!

O que isso quer dizer? Quer dizer que a nossa classe ContaBancaria está se comportando como esperado. Está está enviando uma chamada para o objeto webservice, passando os parâmetros corretamente no momento em que é feito um depósito.
Para garantir isso, vamos escrever mais um teste, passando outros valores:

[TestMethod]
public void Deve_Realizar_Deposito_15_E_Chamar_WebService_Passando_Deposito_E_Valor_15()
{
    var mockWebService = new Mock<IWebServiceContas>();
    mockWebService
        .Setup(ws => ws.RegistrarOperacaoEmConta("Depósito", 15));
 
    var conta = new ContaBancaria(10, mockWebService.Object);
    conta.Depositar(15);
 
    mockWebService.VerifyAll();
}

Este teste irá falhar, pois eu deixei hardcoded a chamada para o webservice dentro do método, para isso vamos alterar a chamada do método:

public void Depositar(decimal valorDoDeposito)
{
    this.SaldoAtual += valorDoDeposito;
 
    this.webServiceContas.RegistrarOperacaoEmConta("Depósito", valorDoDeposito);
}

E finalmente, rodando nossos testes:

Rodando Todos Testes e Testes com Mocks passando

Rodando Todos Testes e Testes com Mocks passando

Bom galera é isso.
Sei que existe muito mais complexidade em realizar testes, usar mocks, etc. E sei também que TDD não é algo que podemos sair aplicando da noite para o dia. É preciso maturidade. No entanto a maturidae só virá com a prática e a utilização.
Corroborando o Giovanni Bassi: “Testar é caro, não testar é mais caro ainda!”.

Neste post vimos como usar mocks, e também vimos como os testes nos ajudaram a encontrar erros, afinal, fizemos algumas alterações no código e alguns testes pararam de rodar. É disso que eu estou falando! É para isso que os testes servem!

Qualquer dúvida podem entrar em contato comigo.

Abraços,
Vinicius Quaiato.