Testing Databases

testify/mock

Mocks are useful if you need to call a method while testing another method, but it has side-effects or you don't want to set it up.

You configure a mock of whatever you’re testing (using an interface) with the same methods as it. Then in the test, you initialise the mocked object, and say “when you see method X called with parameter Y, return this value”.

It's a bit confusing to work out how this works, because it's an interplay of several method calls

// Define the method being mocked
// This is confusing when seen in isolation, because it doesn't
// appear to do anything!
func (m myServiceMock) AddDevice(value int) bool {
	// Record that the method was called, and get the 
	// value it was called with
	args := m.Called(device)

	// Return the first element that was passed in as a return value
	// typed as a Bool. We need to specify type because... Go.
	return args.Bool(0)

	// OR if an args.Type() method doesn't exist for your type, do:
	x = args.Get(0)
	return x.([]yourType)
}

// Perform testing
func TestAddDevice(t *testing.T) {
	myService := new(myServiceMock)

	// The key part - set up the mocked method
  // When AddDevice is called with value=100, return true
	myService.On("AddDevice", 100).Return(true)

	// Returns true
	myService.AddDevice(100)
}

// Define the mocked service
type myServiceMock struct {
	mock.Mock
}

vektra/mockery

Apparently this can generate mocks for your interfaces.

References

https://tutorialedge.net/golang/improving-your-tests-with-testify-go/#mocking helped me wrap my brain around testify/mock (for the second time).