Not sure how to structure your Go web application?

My new book guides you through the start-to-finish build of a real world web application in Go — covering topics like how to structure your code, manage dependencies, create dynamic database-driven pages, and how to authenticate and authorize users securely.

Take a look!

Quick tip: Easy test assertions with Go generics

Published on:

Now that Go 1.18 has been released with support for generics, it's easier than ever to create helper functions for your test assertions.

Using helpers for your test assertions can help to:

  • Make your test functions clean and clear;
  • Keep test failure messages consistent;
  • And reduce the potential for errors in your code due to typos.

To illustrate this, let's say that you have a simple greet() function that you want to test:

package main

import "fmt"

func greet(name string) (string, int) {
    greeting := fmt.Sprintf("Hello %s", name)

    // Return the greeting and its length (in bytes).
    return greeting, len(greeting)
}

In the past, your test for the greet() function would probably look something like this:

package main

import "testing"

func TestGreet(t *testing.T) {
    greeting, greetingLength := greet("Alice")

    // Test assertion to check the returned greeting string.
    if greeting != "Hello Alice" {
        t.Errorf("got: %s; want: %s", greeting, "Hello Alice")
    }

    // Test assertion to check the returned greeting length.
    if greetingLength != 11 {
        t.Errorf("got: %d; want: %d", greetingLength, 11)
    }
}

With Go 1.18, we can use generics and the comparable constraint to create an Equal() helper function which carries out our test assertions. Personally, I like to put this in a reusable assert package.

Like so:

package assert

import "testing"

func Equal[T comparable](t *testing.T, actual, expected T) {
    t.Helper()

    if actual != expected {
       t.Errorf("got: %v; want: %v", actual, expected)
    }
}

And with that in place, the TestGreet() test can be simplified like so:

package main

import (
    "testing"
    "your.module.path/assert" // Import your assert package.
)

func TestGreet(t *testing.T) {
    greeting, greetingLength := greet("Alice")

    assert.Equal(t, greeting, "Hello Alice")
    assert.Equal(t, greetingLength, 11)
}