ASP.NET Core - Realizando Testes Unitários - II
Neste artigo veremos como realizar testes unitáriois na ASP .NET Core usando o xUnit. |
Continuando a primeira parte do artigo vamos criar o projeto de testes.
Na plataforma .NET temos 3 opções de frameworks disponíveis para realizar testes de unidade :
Criando o projeto de testes
Antes de criarmos o projeto de testes vamos apresentar o xUnit.net que será a ferramenta que iremos usar para realizar os testes de unidade em nosso projeto.
O xUnit.net é uma ferramenta de teste de unidade gratuita, de código aberto e focada na comunidade para o .NET Framework.
Ele foi escrito pelo mesmo autor do NUnit v2, e é a última tecnologia para testes unitários para C#, F#, VB.NET e outras linguagens .NET. Ele também trabalha com ReSharper, CodeRush, TestDriven.NET e Xamarin, faz parte da Fundação .NET e opera sob seu código de conduta. Está licenciado sob o Apache 2 (uma licença aprovada pelo OSI).
Vamos abrir a solução APICompras criada na primeira parte do artigo e vamos incluir um novo projeto de testes de unidade.
No menu File selecione Add -> New Project;
A seguir selecione :
Escolha o template xUnit Test Project (.NET Core) e clique em Next :
A seguir informe o nome APIComprasTest e clique em Create.
Teremos o projeto incluído na solução conforme mostra a figura abaixo:
Vamos excluir a classe UnitTest1.cs incluida no projeto e a seguir incluir uma referência ao projeto APICompras.
Clique com o botão direito do mouse sobre o projeto APIComprasTest e a seguir clique em Add Reference;
Na janela Reference Manager marque o projeto ApiCompras e clique em OK:
.
Ao final teremos a nossa solução com a seguinte estrutura contendo os dois projetos:
Configurando o projeto de testes
Vamos agora configurar o projeto de testes criando uma implementação fake do serviço ICompraService para depois injetar o serviço no controlador.
Crie no projeto de testes a classe CompraServiceFake que implementa ICompraService com o código abaixo:
using APICompras.Models;
using APICompras.Services;
using System;
using System.Collections.Generic;
using System.Linq;
namespace APIComprasTest
{
public class CompraServiceFake : ICompraService
{
private readonly List<CompraItem> _compra;
public CompraServiceFake()
{
_compra = new List<CompraItem>()
{
new CompraItem() { Id = 1, Nome = "Tablet SamSung 7",
Fabricante ="SamSung", Preco = 765.00M },
new CompraItem() { Id = 2, Nome = "IPad 7",
Fabricante ="Apple", Preco = 644.00M },
new CompraItem() { Id = 3, Nome = "Notebook Lenovo 13",
Fabricante ="Lenovo", Preco = 987.00M },
new CompraItem() { Id = 4, Nome = "Monitor LG 23",
Fabricante ="LG", Preco = 879.00M },
new CompraItem() { Id = 5, Nome = "HD SSD Asus 1T",
Fabricante ="Assus", Preco = 612.00M }
};
}
public IEnumerable<CompraItem> GetAllItems()
{
return _compra;
}
public CompraItem Add(CompraItem novoItem)
{
novoItem.Id = GeraId();
_compra.Add(novoItem);
return novoItem;
}
public CompraItem GetById(int id)
{
return _compra.Where(a => a.Id == id)
.FirstOrDefault();
}
public void Remove(int id)
{
var item = _compra.First(a => a.Id == id);
_compra.Remove(item);
}
static int GeraId()
{
Random random = new Random();
return random.Next(1, 100);
}
}
}
|
Nesta implementação definimos um código com dados em memória para representar o nosso serviço com dados fictícios.
Agora vamos criar os testes de unidades no controlador ComprasControllerTest, mas antes vamos definir alguns conceitos usados.
xUnit - Conceitos básicos
No xUnit precisamos decorar os métodos de teste com o atributo [Fact], que é usado pelo xUnit para marcar os métodos de testes. Além dos métodos de testes, também podemos ter vários métodos auxiliares na classe de teste.
Com o
XUnit para tornar um método comum em método de
testes basta adicionar [Fact] ou [Theory] acima de
sua assinatura, os atributos diferem apenas no seguinte, para testes sem
parâmetros deve-se usar [Fact], para testes como
parâmetros utiliza-se o [Theory].
Ao escrever testes unitários, em geral seguimos o princípio
AAA : Act, Arrange e
Assert (Organizar, Agir e Assertir):
Arrange - È aqui que você normalmente prepara tudo
para o teste, em outras palavras, prepara a cena para testar (criar os
objetos e configurá-los conforme necessário)
Act - È onde o método que estamos testando é
executado;
Assert - Esta é a parte final do teste em que
comparamos o que esperamos que aconteça com o resultado real da execução do
método de teste;
Os nomes dos métodos de teste devem ser tão descritivos quanto possível. Na
maioria dos casos, é possível nomear o método para que nem seja necessário ler o
código real para entender o que está sendo testado.
No exemplo, usamos a seguinte convenção de nomenclatura :
1 - A primeira parte do nome representa o nome do método
que está sendo testado;
2- A segunda parte do onome nos informa mais sobre o cenário de teste;
3- A última parte do nome é o resultado esperado;
Exemplo :
Get_WhenCalled_ReturnsOKResult (estou
usando a língua inglesa)
Geralmente, a lógica dentro de nossos controladores deve ser mínima e não tão
focada na lógica ou infraestrutura de negócios (acesso a dados etc.).
Queremos testar a lógica do controlador e não as estruturas que estamos usando.
Testando os métodos Action
O primeiro
método que vamos testar é o método Get e vamos
querer verificar o seguinte:
1 - Se o método retorna o OkObjectResult, que
representa o código de resposta HTTP 200;
2 - Se o objeto retornado contém nossa lista CompraItem e todos os nossos itens;
Vamos agora criar a classe ComprasControllerTest no projeto e incluir o código abaixo:
using APICompras.Controllers;
using APICompras.Models;
using APICompras.Services;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using Xunit;
namespace APIComprasTest
{
public class ComprasControllerTest
{
ComprasController _controller;
ICompraService _service;
public ComprasControllerTest()
{
_service = new CompraServiceFake();
_controller = new ComprasController(_service);
}
[Fact]
public void Get_WhenCalled_ReturnsOkResult()
{
// Act
var okResult = _controller.Get();
// Assert
Assert.IsType<OkObjectResult>(okResult.Result);
}
[Fact]
public void Get_WhenCalled_ReturnsAllItems()
{
// Act
var okResult = _controller.Get().Result as OkObjectResult;
// Assert
var items = Assert.IsType<List<CompraItem>>(okResult.Value);
Assert.Equal(3, items.Count);
}
}
}
|
Criamos uma
instância do objeto ComprasController na classe de
teste e essa é a classe que queremos testar. É importante observar aqui que esse
construtor é chamado antes de cada método de teste, o que significa que estamos
sempre redefinindo o estado do controlador e realizando o teste no novo objeto.
Isso é importante porque os métodos de teste não devem depender uns dos outros e
devemos obter os mesmos resultados de teste, não importa quantas vezes
executemos os testes e em que ordem os executamos.
Agora no menu Test clique em Windows->Test Explorer para abrir a janela do Test Explorer:
Nesta janela iremos executar e acompanhar a execução dos testes de unidade.
Conforme você executa, grava e executa novamente os testes, o Test Explorer exibe os resultados nos grupos padrão de Testes com Falha, Testes Aprovados, Testes Ignorados e Testes Não Executados. Você pode também alterar a forma como o Test Explorer agrupa seus testes.
O painel de detalhes de teste exibe as seguintes informações:
Se o teste falhar, o painel de detalhes também exibe:
Executando todos (Run All) os dois testes que criamos vamos obter o seguinte resultado:
Os dois métodos foram executandos sendo que 1 passou e 1 falhou.
O método Get_WhenCalled_ReturnOkResult passou e vemos um ícon verde indicando que tudo esta ok.
No método Get_WhenCalledResultAllItens falhou pois o resultado final esperado era de 3 itens mas como temos 5 itens o teste falhou.
Observe que a mensagem de erro indica que era esperado 3 mas retornou 5 e na janela à esquerda temos detalhes do teste indicando o arquivo e a linha onde ocorreu o erro.
Vamos corrigir o código do teste alterando o valor do esperado de 3 para 5 e executando novamente o teste.
Pronto ! agora temos os dois testes de unidades executados com sucesso.
É possível executar um teste específico apenas selecionando o teste desejado com o botão direito do mouse e clicando em “Run Selected Tests”.
Também é possível executar os testes via linha de comando, para isso é necessário instalar via NuGet o pacote xunit.runner.console.
Agora que já sabemos como testar na próxima parte do artigo vamos definir os demais testes unitários.
"Amo ao
SENHOR, porque ele ouviu a minha voz e a minha súplica.
Porque inclinou a mim os seus ouvidos; portanto, o invocarei enquanto viver."
Salmos 116:1,2
Veja os
Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique
e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
ASP .NET Core 2 - MiniCurso Básico - Macoratti
ASP .NET Core MVC - CRUD básico com ADO .NET - Macoratti
ASP .NET Core - Implementando a segurança com ... - Macoratti
ASP .NET Core - Iniciando com ASP .NET Core MVC e ... - Macoratti
ASP .NET Core MVC - Criando um site com MySql e EF ... - Macoratti
ASP .NET Core - Gerenciador de Despesas Pessoais com ... - Macoratti
Minicurso ASP .NET Core 2.0 - Apresentando MVC - YouTube
ASP .NET Core - Configurando o ambiente de ... - Macoratti
ASP .NET Core e EF Core - Configurando o ambiente - Macoratti
ASP .NET Core - Como configurar o AutoMapper - Macoratti