Go Tests and Databases | Crit Russell

January 19, 2018

Go Tests and Databases

I had a talk with a friend about unit and integration testing today. They were pointing out that their “tests basically generate 200mb of ‘helloworld’ bytes and write them to a temp file that gets cleaned up after the test.”

That reminded me of a pattern that I’ve been using for my new startup to cleanup database rows after integration testing.

It’s a really simple thing that is paying off in local (to my laptop) record management. If you’ve used anything like an integration testing suite attached to a database then you’ve probably seen your number of rows explode. This might be a good thing if you want to have a ton of records available for prototyping or user testing. Most of the time I don’t need that from my tests (I might run a script to create hundreds of rows in the database deliberately).

Here’s some code:

// tests/users_test.go

func mockUser() (user users.User, deleter func()) {
	var req users.CreateRequest

	req.Name = faker.Name() // faker is my package for creating mock content
	req.Email = faker.Email()
	req.Password = faker.Password(12)
	req.Editor = faker.Email()

	user, err := users.Create(req)

	if err != nil {
		log.Fatal(err.Error())
	}

	return user, func() {
		users.Delete(user.ID)
	}
}

// ... a test somewhere in this package

func TestUserLister(t *testing.T) {
	// make sure there is a record in the local
	// test db setup in this package's 'init'
	_, deleter := mockUser() // not using the returned User on this test

	defer deleter() // cleanup on function exit

	response, err := users.List(10, 0) // limit 10, offset 0

	assert.Nil(t, err) // github.com/stretchr/testify/assert
	assert.NotEmpty(t, response.Users)
	// etc ....
}

The part that helps me most is defer deleter(). Automatic creation and deletion of a db row to get a full pass integration test.

Been really useful so far.

Thoughts/Questions?

© Crit Russell