diff --git a/cmd/api/handlers_test.go b/cmd/api/handlers_test.go index adfc00b..2d6ec20 100644 --- a/cmd/api/handlers_test.go +++ b/cmd/api/handlers_test.go @@ -7,8 +7,9 @@ import ( "log/slog" "net/http" "net/http/httptest" - "strings" "testing" + + "git.runcible.io/learning/pulley/internal/assert" ) func newTestApplication() application { @@ -35,15 +36,12 @@ func TestHealthRoute(t *testing.T) { } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) - if err != nil { - t.Fatal(err) - } + + assert.NilError(t, err) body = bytes.TrimSpace(body) - if !strings.Contains(string(body), "environment: test") { - t.Fatalf("Did not find: %q in response body", "environment: test") - } + assert.StringContains(t, string(body), "environment: test") } func TestCreateMovieHandler(t *testing.T) { @@ -65,15 +63,12 @@ func TestCreateMovieHandler(t *testing.T) { } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) - if err != nil { - t.Fatal(err) - } + + assert.NilError(t, err) body = bytes.TrimSpace(body) - if !strings.Contains(string(body), want) { - t.Fatalf("Did not find: %q in response body", want) - } + assert.StringContains(t, string(body), want) } func TestGetAllMoviesHandler(t *testing.T) { @@ -107,9 +102,7 @@ func TestGetAllMoviesHandler(t *testing.T) { r, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/v1/movies/%s", test.id), nil) t.Logf("Path: %s, Method: %s", r.URL.Path, r.Method) - if err != nil { - t.Fatal(err) - } + assert.NilError(t, err) app := newTestApplication() // want to test with httprouter since we use it to parse context @@ -117,9 +110,8 @@ func TestGetAllMoviesHandler(t *testing.T) { resp := respRec.Result() t.Logf("Code: %d", resp.StatusCode) - if resp.StatusCode != test.wantCode { - t.Fatalf("Got status code '%d', wanted status code '%d'", resp.StatusCode, test.wantCode) - } + assert.Equal(t, resp.StatusCode, test.wantCode) + }) } } diff --git a/internal/assert/assert.go b/internal/assert/assert.go new file mode 100644 index 0000000..3cc90d5 --- /dev/null +++ b/internal/assert/assert.go @@ -0,0 +1,38 @@ +package assert + +import ( + "strings" + "testing" +) + +// Equal a generic function to test equivalence between two values +// of the same type +func Equal[T comparable](t *testing.T, actual, expected T) { + //The t.Helper() function that we’re using in the code above indicates + // to the Go test runner that our Equal() function is a test helper. + // This means that when t.Errorf() is called from our Equal() function, + // the Go test runner will report the filename and line number of the + // code which called our Equal() function in the output. + t.Helper() + + if actual != expected { + t.Errorf("got: %v; want %v", actual, expected) + } +} + +func StringContains(t *testing.T, actual, expectedSubstring string) { + + t.Helper() + + if !strings.Contains(actual, expectedSubstring) { + t.Errorf("got: %q; expected to contain %q", actual, expectedSubstring) + } +} + +func NilError(t *testing.T, actual error) { + t.Helper() + + if actual != nil { + t.Errorf("got: %v; expected: nil", actual) + } +} diff --git a/internal/logging/logging_test.go b/internal/logging/logging_test.go index 1ebdee6..dd9af15 100644 --- a/internal/logging/logging_test.go +++ b/internal/logging/logging_test.go @@ -3,8 +3,9 @@ package logging import ( "bytes" "log/slog" - "strings" "testing" + + "git.runcible.io/learning/pulley/internal/assert" ) func TestParseLevel(t *testing.T) { @@ -45,9 +46,7 @@ func TestParseLevel(t *testing.T) { t.Run(test.name, func(t *testing.T) { got := parseLogLevel(test.level) - if got != test.want { - t.Errorf("got %s, want %s", got, test.want) - } + assert.Equal(t, got, test.want) }) } @@ -61,8 +60,6 @@ func TestInitLogging(t *testing.T) { logger.Info(msg) content := spy.String() - if !strings.Contains(content, msg) { - t.Fatalf("Error comparing messages. Wanted: %q got: %q", msg, content) - } + assert.StringContains(t, content, msg) }