For your database driver, just use pgx. For migrations, tern is fine. For the tiniest bit of sugar around scanning database results into structs, use sqlx instead of database/sql.
I wouldn't recommend using a testing framework in Go: https://go.dev/wiki/TestComments#assert-libraries
Here's how I do dependency injection:
func main() {
foo := &Foo{
Parameter: goesHere,
}
bar := &Bar{
SomethingItNeeds: canJustBeTypedIn,
}
app := &App{
Foo: foo,
Bar: bar,
}
app.ListenAndServe()
}
If you need more complexity, you can add more complexity. I like "zap" over "slog" for logging. I am interested in some of the DI frameworks (dig), but it's never been a clear win to me over a little bit of hand-rolled complexity like the above.A lot of people want some sort of mocking framework. I just do this:
- func foo(x SomethingConcrete) {
- x.Whatever()
- }
+ interface Whateverer { Whatever() }
+ func foo(x Whateverer) {
+ x.Whatever()
+ }
Then in the tests: type testWhateverer {
n int
}
var _ Whateverer = (*testWhateverer)(nil)
func (w *testWhateverer) Whatever() { w.n++ }
func TestFoo(t *testing.T) {
x := &testWhateverer{}
foo(x)
if got, want := x.n, 1; got != want {
t.Errorf("expected Whatever to have been called: invocation count:\n got: %v\n want: %v", got, want)
}
}
It's easy. I typed it in an HN comment in like 30 seconds. Whether or not a test that counts how many times you called Whatever is up to you, but if you need it, you need it, and it's easy to do.