How to Design for Testability with DI in Go

Use interfaces and constructor injection to swap real dependencies with mocks for isolated, fast Go tests.

Design for testability in Go by defining interfaces for external dependencies and injecting them into your functions or structs. This allows you to swap real implementations with mocks during testing without changing your production code.

type Repository interface {
    Get(id string) (*User, error)
}

type UserService struct {
    repo Repository
}

func NewUserService(repo Repository) *UserService {
    return &UserService{repo: repo}
}

func (s *UserService) GetUser(id string) (*User, error) {
    return s.repo.Get(id)
}

In tests, you pass a mock implementation of Repository to NewUserService instead of the real database client.