Pular para o conteúdo
.NETMocks com Moq
Módulo 02Fundamentos de Aplicação

Mocks com Moq

intermediario 28 min de leitura·Atualizado · .NET 9
Resumo

Um mock é uma implementação falsa de uma dependência (interface), criada em tempo de teste. Com Moq você configura o comportamento (Setup) e verifica interações (Verify), isolando a unidade sob teste de banco, rede e outros serviços.

1. Objetivos de Aprendizagem#

  • Criar mocks de interfaces com Moq.
  • Configurar retornos com Setup.
  • Verificar chamadas com Verify.

2. Pré-requisitos#

  • Interfaces (Módulo 05), DI (Módulo 12) e xUnit (tópico 15.1).

3. Conceito#

Ao testar um serviço que depende de IRepositorio, você não quer tocar o banco real. Um mock implementa a interface em memória, com comportamento que você define:

  • Setup: "quando chamarem este método com estes argumentos, retorne isto".
  • Verify: "confirme que este método foi chamado (quantas vezes)".

O porquê: testes rápidos, determinísticos e focados na lógica da unidade — é aqui que a injeção de dependência (depender de interfaces) paga dividendos.

4. Mão na Massa#

4.1. Setup#

Shell
dotnet new xunit -n Catalog.Tests3
dotnet add Catalog.Tests3 package Moq

4.2. Implementação Passo a Passo#

  1. Dependência e serviço:
C#
public interface IRepositorioProduto
{
    Task<decimal?> ObterPrecoAsync(Guid id);
}

public class ServicoPreco
{
    private readonly IRepositorioProduto _repo;
    public ServicoPreco(IRepositorioProduto repo) => _repo = repo;

    public async Task<decimal> ComImpostoAsync(Guid id)
    {
        var preco = await _repo.ObterPrecoAsync(id)
            ?? throw new InvalidOperationException("Produto sem preço.");
        return preco * 1.1m;
    }
}
  1. Teste com mock (Setup + Verify):
C#
using Moq;
using Xunit;

public class ServicoPrecoTests
{
    [Fact]
    public async Task ComImposto_AplicaSobrePrecoDoRepositorio()
    {
        // Arrange
        var id = Guid.NewGuid();
        var repo = new Mock<IRepositorioProduto>();
        repo.Setup(r => r.ObterPrecoAsync(id)).ReturnsAsync(100m);
        var servico = new ServicoPreco(repo.Object);

        // Act
        var resultado = await servico.ComImpostoAsync(id);

        // Assert
        Assert.Equal(110m, resultado);
        repo.Verify(r => r.ObterPrecoAsync(id), Times.Once);
    }
}

4.3. Executando#

Shell
dotnet test

5. Exemplo Completo#

O mock de IRepositorioProduto retorna 100m sem tocar o banco; o teste valida o cálculo (110m) e confirma que o repositório foi consultado uma vez. Rápido, isolado e determinístico.

6. Boas Práticas e Armadilhas#

FaçaEvite
Mockar interfaces (fronteiras: repositórios, serviços externos)Mockar tipos concretos ou tudo indistintamente
Verificar interações relevantes com VerifySobre-especificar (testes frágeis que quebram a cada refatoração)
Usar mocks para I/O (banco, rede)Mockar lógica de negócio que deveria ser testada de verdade
Atenção

teste comportamento, não implementação. Verificar chamadas demais acopla o teste aos detalhes internos e o torna frágil. Prefira asserir o resultado observável sempre que possível.

7. Segurança e Produção#

  • Isolar dependências externas mantém a suíte rápida e confiável no CI. Testes que dependem de rede/banco real são lentos e instáveis — reserve-os para testes de integração dedicados.

8. Exercícios#

  • Fácil: crie um mock que retorna um valor fixo com Setup.
  • Médio: verifique que um método do mock foi chamado exatamente uma vez.
  • Desafio: teste o caminho de erro (repositório retorna null) e confirme a exceção com Assert.Throws/ThrowsAsync.

9. Resumo#

Moq cria implementações falsas de interfaces: Setup define retornos, Verify confere interações. Isso isola a unidade de I/O, tornando os testes rápidos e determinísticos. Teste comportamento, não implementação.

10. Próximos Passos#

Você concluiu os fundamentos de .NET. Está pronto para o curso de Web API com ASP.NET Core (livro.zip), que aplica tudo isso na prática.

11. Referências#

15-03 — Mocks com Moq | Curso ASP.NET Core