Software Engineer / SRE
slides: bisconti.cloud
contact: g.dev/julien
“A little copying is better than a little dependency.”
“The bigger the interface, the weaker the abstraction.”
“Errors are values.”
An interface is a set of method signatures.
Rule: If your type has the methods, it fits the interface. No implements
keyword needed.
(Structural Typing / Duck Typing)
// The interface
type Reader interface {
Read(p []byte) (n int, err error)
}
// A function that accepts any Reader
func logData(r io.Reader) { io.Copy(os.Stdout, r) }
// Two different types can be passed to logData
var f *os.File
var s *strings.Reader
logData(f)
logData(s)
No Third-Party Mocking Libraries Needed!
// Interface defined by consumer
type UserStorer interface {
GetUser(id int) (*User, error)
}
// Real implementation
type DB struct{ ... }
func (db *DB) GetUser(id int) (*User, error) {
// ... real db logic
}
// Mock implementation for tests
type mockUserStorer struct{}
func (m *mockUserStorer) GetUser(id int) (*User, error) {
return &User{ID: id, Name: "Mock User"}, nil
}
// In your test:
func TestGetUserEndpoint(t *testing.T) {
mockDB := &mockUserStorer{}
handler := NewHandler(mockDB) // Handler depends on UserStorer
// ... test the handler
}
Simple, Opinionated, Effective
go test
is all you need.thing_test.go
lives in the same package.func TestAdd(t *testing.T) {
testCases := []struct {
name string
a, b int
want int
}{
{"positive numbers", 2, 3, 5},
{"negative numbers", -1, -5, -6},
{"zero", 5, 0, 5},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got := Add(tc.a, tc.b)
if got != tc.want {
t.Errorf("got %d; want %d", got, tc.want)
}
})
}
}
See also Generic interfaces
Go has no “try…catch”.
Functions that can fail return two things: the result and an error
value.
value, err := someFunction()
The error
type is just an interface:
type error interface { Error() string }
Read Go Blog
f, err := os.Open("my_file.txt")
if err != nil {
log.Fatalf("failed to open file: %v", err)
}
defer f.Close()
// ... do something with f ...
Philosophy of Simplicity
↓
Small, Composable Interfaces
↓
Explicit, Value-based Error Handling
Go’s features aren’t isolated; they are a cohesive system designed for clarity and reliability.
context.Context is an interface.
Read Go Blog
and I'm sorry 🙏
If you had to maintain my code
I hope you learned more by maintaining it
than me by writing it
Slides made with Reveal.js and hugo-reveal
Software Engineer / SRE
slides: bisconti.cloud
contact: g.dev/julien