gomock para Go: guia completo de mocking de interfaces
1. O que é e para que serve
No desenvolvimento moderno com Go, os testes desempenham um papel fundamental. No entanto, o código frequentemente depende de sistemas externos: bancos de dados, clientes HTTP, sistemas de arquivos ou outros microsserviços. Testar esse código isoladamente é difícil, pois essas dependências exigem um ambiente real. É aqui que entra o gomock — uma biblioteca poderosa para gerar e usar mocks (simulações) para interfaces Go.
O gomock permite criar automaticamente implementações de interfaces que se comportam de forma previsível: retornam valores definidos, verificam a ordem das chamadas, contam o número de acessos e até simulam erros. Isso torna os testes unitários rápidos, determinísticos e independentes de recursos externos. A biblioteca se integra perfeitamente com o pacote nativo testing e é o padrão de facto para mocking na comunidade Go.
O principal valor do gomock é que você testa o comportamento do seu código, não sua implementação. Você verifica se seu serviço chama corretamente os métodos das dependências com os argumentos certos e processa os resultados adequadamente. Isso é especialmente importante ao seguir os princípios SOLID e o padrão de Injeção de Dependência (Dependency Injection).
2. Instalação
Para trabalhar com gomock, você precisa instalar dois componentes:
- Biblioteca gomock — contém o runtime para trabalhar com mocks.
- Ferramenta mockgen — gerador de código de mock a partir de interfaces.
A instalação é feita através do gerenciador de pacotes padrão do Go:
# Instalar a biblioteca
go get github.com/golang/mock/gomock
# Instalar a ferramenta mockgen
go install github.com/golang/mock/mockgen@v1.6.0
Após a instalação, verifique se o mockgen está disponível no seu PATH. Teste com o comando:
mockgen --version
Se você usa Go 1.16+, é recomendável adicionar o mockgen ao arquivo tools.go para versionamento:
// tools.go
// +build tools
package tools
import (
_ "github.com/golang/mock/mockgen"
)
3. Início rápido — exemplo mínimo funcional
Vamos a um exemplo simples. Suponha que temos uma interface Greeter que queremos simular.
// greeter.go
package main
// Greeter — interface que será simulada
type Greeter interface {
Greet(name string) string
}
// Service usa Greeter
type Service struct {
greeter Greeter
}
func NewService(g Greeter) *Service {
return &Service{greeter: g}
}
func (s *Service) SayHello(name string) string {
return s.greeter.Greet(name)
}
Primeiro, geramos o mock:
mockgen -source=greeter.go -destination=mock_greeter.go -package=main
Agora escrevemos o teste:
// greeter_test.go
package main
import (
"testing"
"github.com/golang/mock/gomock"
)
func TestSayHello(t *testing.T) {
// Criamos o controlador gomock
ctrl := gomock.NewController(t)
defer ctrl.Finish()
// Criamos o mock de Greeter
mockGreeter := NewMockGreeter(ctrl)
// Configuramos a expectativa: ao chamar Greet("Alice"), retornar "Olá, Alice!"
mockGreeter.EXPECT().Greet("Alice").Return("Olá, Alice!")
// Criamos o serviço com o mock
service := NewService(mockGreeter)
// Chamamos o método testado
result := service.SayHello("Alice")
// Verificamos o resultado
if result != "Olá, Alice!" {
t.Errorf("Esperado 'Olá, Alice!', mas obteve '%s'", result)
}
}
Execute o teste:
go test -v
Você verá que o teste passa com sucesso. O mock verificou automaticamente que o método foi chamado com os argumentos corretos.
Também na biblioteca
Geração de PDF em C++: visão geral das bibliotecas e exemplos de código
ts-mockito para TypeScript: guia completo com exemplos
WireMock.Net para C# (.NET): guia completo com exemplos
Trabalho com imagens em PHP: redimensionamento, corte e otimização com GD e Imagick