Spec Backend Com Golang E Gin • Trilha Progressiva em 4 Níveis


🎯 Nível 1: Fundamentos

Problema 15.1 — Teste Unitário de Handler Gin com net/http/httptest

Contexto: Teste Unitário de Handler Gin com net/http/httptest no contexto de Testes Automatizados com httptest e Testify.

Requisitos de Execução:

  1. Criar gravador httptest.NewRecorder(), simular requisição GET /ping e validar status code 200.

Resultado Esperado

Teste GET /ping: Status 200 e body validado.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_15_1_SeuNome
  2. Envie na tarefa: Atividade Cap 15 - Testes Automatizados com httptest e Testify
🔑 Gabarito de Código & Solução Comentada
// handlers_test.go
package main

import (
	"net/http"
	"net/http/httptest"
	"testing"
	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
)

func TestPingHandler(t *testing.T) {
	gin.SetMode(gin.TestMode)
	r := gin.New()
	r.GET("/ping", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"msg": "pong"}) })

	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/ping", nil)
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusOK, w.Code)
	assert.Contains(t, w.Body.String(), "pong")
}

🔍 Nível 2: Prática

Problema 15.2 — Mocks de Repositório com stretchr/testify/mock

Contexto: Mocks de Repositório com stretchr/testify/mock no contexto de Testes Automatizados com httptest e Testify.

Requisitos de Execução:

  1. Criar mock de ProdutoRepository usando mock.Mock e testar regras de negócio do ProdutoService.

Resultado Esperado

Service testado isoladamente com mock de banco de dados aprovado.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_15_2_SeuNome
  2. Envie na tarefa: Atividade Cap 15 - Testes Automatizados com httptest e Testify
🔑 Gabarito de Código & Solução Comentada
// mock_test.go
package main

import (
	"testing"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
)

type MockRepo struct {
	mock.Mock
}

func (m *MockRepo) BuscarPreco(id int) float64 {
	args := m.Called(id)
	return args.Get(0).(float64)
}

func TestCalculoDesconto(t *testing.T) {
	mockRepo := new(MockRepo)
	mockRepo.On("BuscarPreco", 1).Return(100.0)
	preco := mockRepo.BuscarPreco(1)
	assert.Equal(t, 100.0, preco)
}

⚡ Nível 3: Integração

Problema 15.3 — Testes de Integração com Banco SQLite em Memória

Contexto: Testes de Integração com Banco SQLite em Memória no contexto de Testes Automatizados com httptest e Testify.

Requisitos de Execução:

  1. Configurar suite de testes que execute migrações em banco SQLite in-memory antes de cada teste.

Resultado Esperado

Teste de integração executado com banco isolado em memória.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_15_3_SeuNome
  2. Envie na tarefa: Atividade Cap 15 - Testes Automatizados com httptest e Testify
🔑 Gabarito de Código & Solução Comentada
// integration_test.go
package main

import (
	"testing"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"github.com/stretchr/testify/assert"
)

func TestDatabaseIntegration(t *testing.T) {
	db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
	assert.NoError(t, err)
	assert.NotNil(t, db)
}

🏆 Nível 4: Desafio Corporativo

Problema 15.4 — Benchmarking de Performance com testing.B

Contexto: Benchmarking de Performance com testing.B no contexto de Testes Automatizados com httptest e Testify.

Requisitos de Execução:

  1. Escrever benchmark BenchmarkJsonSerialization(b *testing.B) medindo allocs/op e ns/op de serialização.

Resultado Esperado

Benchmark: 5.000.000 ops/s com 0 alocações por operação.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_15_4_SeuNome
  2. Envie na tarefa: Atividade Cap 15 - Testes Automatizados com httptest e Testify
🔑 Gabarito de Código & Solução Comentada
// benchmark_test.go
package main

import (
	"encoding/json"
	"testing"
)

type DadosTeste struct {
	ID   int    `json:"id"`
	Nome string `json:"nome"`
}

func BenchmarkJsonSerialization(b *testing.B) {
	d := DadosTeste{ID: 10, Nome: "Benchmark"}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = json.Marshal(d)
	}
}