Aula 19 - Testes Automatizados com xUnit, Moq e FluentAssertions 🧪
Objetivo Pedagógico
Objetivo: Estratégia de testes automatizados corporativos em .NET 8: Testes unitários com xUnit e Moq, asserções expressivas com FluentAssertions e testes de integração com Testcontainers.
📑 1. Fundamentos Teóricos & Análise Técnica
A confiabilidade de sistemas empresariais em .NET é garantida por uma pirâmide de testes disciplinada. A combinação da biblioteca xUnit, a ferramenta de simulação Moq e as asserções fluentes do FluentAssertions constitui o padrão de excelência para testes de software em C#.
- Testes Unitários com xUnit e Moq: Isolam a unidade de código sob teste (System Under Test - SUT), substituindo dependências externas (como repositórios de banco de dados ou gateways de pagamento) por objetos simulados (mocks), verificando chamadas com
Verify()e configurando respostas comSetup(). - FluentAssertions: Substitui asserções antiquadas do tipo
Assert.Equal(esperado, obtido)por uma sintaxe fluente e humanizada (resultado.Should().Be(esperado)), gerando mensagens de diagnóstico detalhadas e visualmente informativas quando um teste falha. - Testes de Integração com Testcontainers: Inicializa contêineres Docker reais de banco de dados (SQL Server, PostgreSQL) durante a execução dos testes, garantindo que queries SQL complexas funcionem exatamente como esperado sem mocks artificiais.
📐 Arquitetura Conceitual & Diagrama de Fluxo
flowchart LR
Unit["Testes Unitários (xUnit + Moq)<br>Isolamento Rápido em Memória"] --> SUT["Regra de Negócio / Service"]
Integration["Testes de Integração (WebApplicationFactory)"] --> RealDB["Testcontainers (Docker Banco Real)"]
SUT --> Assertions["FluentAssertions (result.Should().BeSuccess())"]
RealDB --> Assertions
Assertions --> Report["Relatório de Cobertura e CI Verde"]
style Unit fill:#e1f5fe,stroke:#01579b
style Integration fill:#fff3e0,stroke:#e65100
style Assertions fill:#e8f5e9,stroke:#2e7d32 🔍 Pilares e Diretrizes Técnicas
Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Padrão AAA (Arrange, Act, Assert): Estruturação clara das fases de preparação, execução e validação do teste. - Simulação Estrita com Moq: Verificação determinística de que métodos críticos de auditoria ou gravação foram invocados. - Asserções Autodescritivas: O FluentAssertions explica claramente a divergência estrutural em falhas de coleções ou objetos aninhados. - Banco de Dados Real em Testes: Eliminação de divergências entre provedores in-memory e dialetos SQL de produção via Testcontainers.
🛠️ 2. Implementação Prática em C#, xUnit, Moq e Testcontainers
Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:
// OrderServiceTests.cs (Testes Unitários com xUnit, Moq e FluentAssertions)
using Xunit;
using Moq;
using FluentAssertions;
namespace Empresa.Core.Tests;
public class OrderServiceTests
{
private final Mock<IOrderRepository> _orderRepoMock = new();
private final Mock<IPaymentGateway> _paymentMock = new();
[Fact]
public async Task ProcessOrder_ValidOrder_ReturnsSuccessResult()
{
// 1. Arrange (Preparação)
var orderId = Guid.NewGuid();
_paymentMock.Setup(p => p.ChargeAsync(It.IsAny<decimal>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
var service = new OrderProcessingService(_orderRepoMock.Object, _paymentMock.Object);
// 2. Act (Execução)
var result = await service.ExecuteOrderAsync(orderId, 100m, CancellationToken.None);
// 3. Assert (Validação com FluentAssertions)
result.IsSuccess.Should().BeTrue();
result.Message.Should().Contain("Processado com sucesso");
// Verifica se o pagamento foi chamado exatamente 1 vez
_paymentMock.Verify(p => p.ChargeAsync(100m, It.IsAny<CancellationToken>()), Times.Once);
}
}
💡 Análise Passo a Passo do Código
- Criação de Mocks com Moq:
_paymentMock.Setup(...)programa o comportamento esperado da dependência externa de forma isolada. - Sintaxe com Should():
result.IsSuccess.Should().BeTrue()expressa a intenção do teste de maneira limpa e intuitiva. - Verificação de Invocação:
Times.Oncegarante que nenhuma cobrança financeira seja efetuada em duplicidade pelo fluxo.
🎯 3. Próximos Passos & Sequência Didática
-
Slides da Aula
-
Quiz de Fixação
-
Exercícios Práticos
-
Desafio de Projeto