Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The testify documentation will have more information about what methods these mocks will have and how to use them.

Assertions in tests

We use https://github.com/stretchr/testify for writing assertions in tests. This has 2 common operations

  • 'assert' functions will fail the test if the assertion is incorrect, but the test will continue to run.
  • 'require' functions will fail the test and immediately stop the test if the assertion is incorrect.

'require' should be used when it's impossible to continue the test, such as if an unrecoverable error happens during test setup or if a particular object used is not valid:

Code Block
object, err := GetObject()
require.NoError(t, err)
require.NotNil(t, object)

object.DoThing()

If a test can continue after something fails, use 'assert' instead.

Sub-tests

If you are writing a test where there are multiple 'sub tests' (such as checking the behaviour of a certain endpoint with multiple different data inputs), Use t.Run() to separate out these sub-tests.

If you have a test setup like this:

Code Block
func TestFunction(t *testing.T) {
	tests := []struct {
		name string
		input string
	}{
		{
			...
		},
	}

	for _, test := range tests {
		err := Function(test.input)
		require.NoError(t, err)
	}
}

Then as soon as any test runs into an error, it will implicitly fail all other tests as well. Instead, use sub-tests like this:

Code Block
	for _, test := range tests {
		t.Run("test.name", func(t *testing.T) {
			err := Function(test.input)
			require.NoError(t, err)
		})
	}

Creating GCP API clients

When creating an API client (for example, a logging client that is used to read logs from the GCP API) and you only ever want to read data, pass a 'WithScope' option to the constructor to limit what the client can do:

...