< up
2025-01-10

Generic swapping in go

When writing tests, overriding global values/defaults1 can become pretty handy for mocking. But as always with global resources, they need to be used carefully2. Otherwise other tests may behave strangely. Therefore a test should make sure those values are reset to its original value regardless of the test result.

Here you go: A generic swapper that gives you a resetter that can be easily called via defer (playground):

func Swap[T any](target *T, newValue T) func() {
  var original T
  original, *target = *target, newValue
  return func() {
    *target = original
  }
}

You can even use it with defer directly:

func HTTPTest(t *testing.T){
  defer Swap(http.DefaultClient, myClient)()

  ...
}

Don’t forget the additional empty parenthesis at the end to call the returned function. Otherwise the swap takes only place on defer.

+hf


  1. Think of net/http’s default client that can handily be overridden for mocking.
  2. Or not mutable at all. In the end, state is the developers greatest fear. Can you imagine a stateless world? Pretty boring, right?