This skill should be used when writing, refactoring, or testing Go code...
This skill provides comprehensive guidelines for idiomatic Go development with a Test-Driven Development (TDD) approach. Follow these patterns when writing Go code, creating tests, organizing projects, or refactoring existing code.
When implementing a new feature in an existing Go project:
*_test.go file with testify/require testsmocks/ subfolderWhen creating a new Go service or package from scratch:
/cmd, /internal, /pkg)go mod init with appropriate module pathFollow these seven core principles for all Go development:
Write tests before implementation. Tests should be easy to read and favor verbosity over abstraction.
All unit tests must use github.com/stretchr/testify/require for assertions.
Generate mocks using mockery. Mocks must be localized in a mocks/ subfolder next to the interface being mocked.
Avoid table-driven tests. Write explicit test functions for each scenario.
Keep positive (success) and negative (error) test cases in separate test functions.
Never ignore errors. Always handle them explicitly or return them to the caller.
Design interfaces with few methods. Use composition over large interfaces.
any Instead of interface{}For generic types, prefer any over interface{} (Go 1.18+).
project-root/
āāā cmd/ # Main applications
ā āāā myapp/
ā āāā main.go
āāā internal/ # Private application code
ā āāā handler/ # HTTP handlers
ā ā āāā handler.go
ā ā āāā handler_test.go
ā ā āāā mocks/ # Mocks for handler interfaces
ā āāā service/ # Business logic
ā ā āāā service.go
ā ā āāā service_test.go
ā ā āāā mocks/
ā āāā repository/ # Data access
ā āāā repository.go
ā āāā repository_test.go
ā āāā mocks/
āāā pkg/ # Public library code
ā āāā client/
ā āāā client.go
ā āāā client_test.go
ā āāā mocks/
āāā api/ # API definitions (OpenAPI, protobuf)
āāā configs/ # Configuration files
āāā go.mod
āāā go.sum
āāā README.md
// Unit test with mock
func TestServiceCreate(t *testing.T) {
mockRepo := mocks.NewRepository(t)
mockRepo.On("Save", mock.Anything).Return(nil)
svc := NewService(mockRepo)
err := svc.Create(context.Background(), data)
require.NoError(t, err)
mockRepo.AssertExpectations(t)
}
// Separate negative test
func TestServiceCreate_RepoError(t *testing.T) {
mockRepo := mocks.NewRepository(t)
mockRepo.On("Save", mock.Anything).Return(errors.New("db error"))
svc := NewService(mockRepo)
err := svc.Create(context.Background(), data)
require.Error(t, err)
require.Contains(t, err.Error(), "db error")
}
handler, service)user_service.go, user_service_test.go)UserService, HTTPHandler)-er suffix (Reader, Writer, UserRepository)Use this table to find detailed guidance for specific tasks:
| If You Need To... | See This Resource |
|---|---|
| Set up a new Go project structure | Project Structure |
| Understand Go naming conventions | Naming Conventions |
| Write tests with TDD, testify/require, and mockery | Testing Guide |
| Organize packages, interfaces, and dependencies | Code Organization |
| Handle errors idiomatically | Error Handling |
| Work with goroutines, channels, and context | Concurrency Patterns |
| Manage dependencies and go.mod | Dependencies |
| See complete working examples | Complete Examples |
This skill includes detailed reference documentation in the references/ directory. Claude will load these resources as needed when working on specific tasks.