I’m developing my own budgeting app using Go and have been using it to learn new things as well. For testing, because I’m TDD’ing the entire project, I decided to just use the built-in Go testing framework. I use Ginkgo at work and enjoy it, but decided to see what vanilla testing in Go is like.

After writing a bunch of tests for a lot of my boilerplate functions, I quickly had a lot of duplicated set-up code that looked like this at the start of all my tests:

g := NewGomegaWithT(t)

db, err := createTestDb()
g.Expect(err).To(BeNil(), ErrorDidNotOccur)

api := NewApi(db, SelectedQueryLang)

I was having trouble figuring out how to pull this out into it’s own function. Finally I saw a Stack Overflow answer that provided me with a solution.

Here’s how you create your own BeforeEach() function when using Go’s testing framework.

First, create a struct that will hold the objects your test needs to access. Mine looks like this:

type TestingBasics struct {
    GoMega *GomegaWithT
    Db     *sql.DB
    Api    *api
}

Then create your BeforeEach() function that will create this struct for your tests.

func BeforeEach(t *testing.T, SelectedQueryLang *QueryLang) (tb TestingBasics) {
    tb.GoMega = NewGomegaWithT(t)

    var err error
    tb.Db, err = createTestDb()
    tb.GoMega.Expect(err).To(BeNil(), ErrorDidNotOccur)

    tb.Api = NewApi(tb.Db, SelectedQueryLang)

    return tb
}

Now all you need to do is call BeforeEach() at the beginning of your tests. I was able to reduce 4 lines of code down to 1 across all of my tests. Now the start of each of my tests look like this:

t.Run("should add one transaction", func(t *testing.T) {
    tb := BeforeEach(t, SelectedQueryLang)

This can definitely be cleaned up even further, to the point where I wouldn’t even need to call BeforeEach() at the start of each test. At that point though, I might as well have gone with Ginkgo. For me and this project, I am fine with this set up.