C# - Realizando Testes Unitários com XUnit e Moq
Neste artigo veremos como realizar testes de unidade usando o XUnit e o Moq. |
A realização de testes de unidade é uma abordagem de teste de software que é executada em tempo de desenvolvimento para testar o menor componente de qualquer software.
Eu já apresentei os fundamentos do XUnit neste artigo: C# - Realizando Testes Unitários com XUnit
Hoje veremos como usar o Moq para realizar testes unitários usando o XUnit.
Existem muitos frameworks que podemos usar para mocar objetos ou realizar o mocking em nossos projetos na plataforma .NET e neste artigo eu vou tratar do framework Moq.
O que é Moq ?
Moq é
uma biblioteca para mocar objetos para a plataforma .NET desenvolvida
para tirar o máximo proveito de recursos como Linq, árvores de expressão,
expressões lambdas, etc.
Assim, ela suporta a mocagem de interfaces bem como classes. Sua API é
extremamente simples e direta, e não requer nenhum conhecimento ou experiência
prévia com os conceitos de mocking.
A sua instalação pode se feita via Nuget ou manualmente como veremos no projeto exemplo.
Criando o projeto C#
Vamos criar um projeto do tipo Console para .NET Core no VS 2019 Community chamado CShp_UnitTestMoq;
Neste projeto vamos criar uma interface chamada ICalculadora com o seguinte código:
public interface ICalculadora
{
(string operacao, double resultado) Calcular(string operacao, double a, double b);
}
|
Note que o método Calcular() retorna dois valores : uma string operacao e um double resultado.
A seguir crie uma classe chamada Calculadora que implementa esta interface:
using System;
namespace CShp_UnitTestMoq
{
public class Calculadora : ICalculadora
{
public (string operacao, double resultado) Calcular(string operacao, double a, double b)
{
(string operacao, double resultado) resultadoOperacao;
double c;
switch (operacao)
{
case "somar":
c = a + b;
break;
case "subtrair":
c = a - b;
break;
case "multiplicar":
c = a * b;
break;
case "dividir":
c = Math.Round(a / b,2);
break;
default:
c = a + b;
break;
}
resultadoOperacao = (operacao, c);
return resultadoOperacao;
}
}
}
|
Temos aqui uma classe bem simples com algumas operações matemáticas que iremos usar apenas para ilustrar a utilização do XUnit com o Moq.
Vamos agora criar uma classe MaquinaCalculadora com o código a seguir:
namespace CShp_UnitTestMoq
{
public class MaquinaCalculadora
{
private ICalculadora calc;
public MaquinaCalculadora() : this(new Calculadora())
{}
public MaquinaCalculadora(ICalculadora obj)
{
this.calc = obj;
}
public (string operacao, double resultado) Calcular(string tipoOperacao, double a, double b)
{
return calc.Calcular(tipoOperacao, a, b);
}
}
}
|
Criando o projeto de Teste
Vamos agora criar o projeto de teste na mesma solução.
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 CShp_XUnitTest clique em Create.
Vamos incluir uma referência ao projeto Cshp_Calculos.
Clique com o botão direito do mouse sobre o projeto CShp_XUnitTest e a seguir clique em Add Reference;
Na janela Reference Manager marque o projeto CShp_UnitTestMoqe clique em OK.
Agora vamos incluir uma referência ao Moq no projeto de testes via menu Tools -> Manage Nuget Packages for Solution;
Ao final teremos a nossa solução contendo os dois projetos.
Criando os testes de unidade
Vamos aproveitar a classe UnitTest1 e criar os casos de testes iniciando com o teste de unidade para o método Somar.
Crie na classe CalculoUnitTest o código a seguir que representa nosso primeiro caso de teste de unidade:
Neste caso de teste de unidade estamos somando os números 3.2 e 4.5 e esperamos o resultado igual a 7.7.
Estamos criando um objeto mock usando a interface ICalculadora e a seguir especificando uma configuração para invocar a operação 'somar' esperando o retorno igual a 7.7.
Depois criamos uma instância da classe MaquinaCalculadora() passando o objeto mocado e os números para realizar a operação.
Ao final definimos o que esperamos obter com a operação e resultado para indicar que o teste passou.
Agora no menu Test clique em Windows->Test Explorer para abrir a janela do Test Explorer:
Temos a janela exibindo no lado esquerdo o nosso teste de unidade e acima um menu com opções que permite controlar a execução dos testes. No lado direito temos os detalhes do teste selecionado.
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:
Para o nosso teste temos que o teste passou e a sua duração.
Vamos agora definir os casos de testes para as demais operações:
using CShp_UnitTestMoq;
using Moq;
using Xunit;
namespace CShp_XUnitTest
{
public class UnitTest1
{
[Fact]
public void Somar_Dois_Numeros()
{
// Arrange
Moq.Mock<ICalculadora> mock = new Moq.Mock<ICalculadora>();
mock.Setup(x => x.Calcular(It.IsAny<string>(), It.IsAny<double>(), It.IsAny<double>())).Returns(("somar", 7.7));
MaquinaCalculadora maqCalc = new MaquinaCalculadora(mock.Object);
// Act
(string operacao, double resultado) op = maqCalc.Calcular("somar", 3.2, 4.5);
// Assert
Assert.Equal("somar", op.operacao);
Assert.Equal(7.7, op.resultado);
}
[Fact]
public void Subtrair_Dois_Numeros()
{
// Arrange
Moq.Mock<ICalculadora> mock = new Moq.Mock<ICalculadora>();
mock.Setup(x => x.Calcular(It.IsAny<string>(), It.IsAny<double>(), It.IsAny<double>())).Returns(("subtrair", -1.3));
MaquinaCalculadora maqCalc = new MaquinaCalculadora(mock.Object);
// Act
(string operacao, double resultado) op = maqCalc.Calcular("subtrair", 3.2, 4.5);
// Assert
Assert.Equal("subtrair", op.operacao);
Assert.Equal(-1.3, op.resultado);
}
[Fact]
public void Multiplicar_Dois_Numeros()
{
// Arrange
Moq.Mock<ICalculadora> mock = new Moq.Mock<ICalculadora>();
mock.Setup(x => x.Calcular(It.IsAny<string>(), It.IsAny<double>(), It.IsAny<double>())).Returns(("multiplicar", 14.4));
MaquinaCalculadora maqCalc = new MaquinaCalculadora(mock.Object);
// Act
(string operacao, double resultado) op = maqCalc.Calcular("multiplicar", 3.2, 4.5);
// Assert
Assert.Equal("multiplicar", op.operacao);
Assert.Equal(14.4, op.resultado);
}
[Fact]
public void Dividir_Dois_Numeros()
{
// Arrange
Moq.Mock<ICalculadora> mock = new Moq.Mock<ICalculadora>();
mock.Setup(x => x.Calcular(It.IsAny<string>(), It.IsAny<double>(), It.IsAny<double>())).Returns(("dividir", 0.71));
MaquinaCalculadora maqCalc = new MaquinaCalculadora(mock.Object);
// Act
(string operacao, double resultado) op = maqCalc.Calcular("multiplicar", 3.2, 4.5);
// Assert
Assert.Equal("dividir", op.operacao);
Assert.Equal(0.71, op.resultado);
}
}
} |
Definimos 4 casos de testes sendo que um já foi executado. Abrindo o Teste Explorer e executando todos os testes iremos obter o seguinte resultado:
Vemos que todos os testes passaram. Você pode continuar definindo outros casos de testes mas o roteiro básico é o que apresentamos acima.
Temos assim uma apresentação dos principais recursos do XUnit para realização de testes de unidade usando o Moq no .NET Core.
Pegue o código do projeto aqui: CShp_UnitTestMoq.zip
"Tendo
sido, pois, justificados pela fé, temos paz com Deus, por nosso Senhor Jesus
Cristo;
Pelo qual também temos entrada pela fé a esta graça, na qual estamos firmes, e
nos gloriamos na esperança da glória de Deus."
Romanos 5:1,2
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#
Testes de Software - Criando e Executando testes unitários ... - Macoratti
Visual Studio - Criando testes unitários - Macoratti
VB .NET - TDD - Test Drive Development - Macoratti
.NET - Usando MOQ em testes unitários - I - Macoratti
Testes de Software - Macoratti
Testes em desenvolvimento de Software - Macoratti
Eng, de Software - Macoratti