testkit

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package testkit provides testing helpers for portsmith Clean Architecture applications.

Testing the service layer (unit, no database)

Use generated mocks via portsmith mock, then test with plain testing.T:

func TestCreateUser(t *testing.T) {
    repo := mocks.NewUserRepository(t)
    repo.On("FindByEmail", mock.Anything, "a@b.com").Return(nil, users.ErrUserNotFound)
    repo.On("Create", mock.Anything, mock.AnythingOfType("*users.User")).Return(nil)

    svc := users.NewService(repo)
    result, err := svc.Create(ctx, users.CreateParams{Email: "a@b.com"})

    testkit.NoError(t, err)
    testkit.Equal(t, "a@b.com", result.Email)
}

Testing the handler layer (HTTP, no database)

func TestUserHandler_Create(t *testing.T) {
    svc := mocks.NewUserService(t)
    svc.On("Create", ...).Return(&users.User{ID: 1}, nil)

    suite := testkit.NewHTTPSuite(t, userHandler.New(svc).Router())
    suite.POST("/users", `{"email":"a@b.com","name":"Alice"}`).
        ExpectStatus(201).
        ExpectJSONPath("$.id", float64(1))
}

Testing the repository layer (integration, SQLite in-memory)

func TestUserRepository_FindByEmail(t *testing.T) {
    db := testkit.NewTestDB(t, &users.User{})
    repo := users.NewRepository(db.DB())
    // ... test repository methods
}

Table-driven tests

testkit.Table(t, []testkit.Case{
    {Name: "success", Run: func(t *testing.T) { ... }},
    {Name: "not found", Run: func(t *testing.T) { ... }},
})

Package testkit provides testing helpers for Clean Architecture Go applications.

Three testing levels are supported:

Service tests (unit, no database)

Use generated mocks (portsmith mock) with the service constructor. testkit provides assertion helpers on top of testing.T.

Handler tests (HTTP, no database)

Use HTTPSuite to make HTTP requests against a gin.Engine:

suite := testkit.NewHTTPSuite(t, router)
suite.POST("/users", `{"email":"a@b.com"}`).
    ExpectStatus(201).
    ExpectJSONPath("$.id", float64(1))

Repository tests (integration, SQLite in-memory)

Use NewTestDB to get a *database.DB backed by SQLite:

db := testkit.NewTestDB(t, &user.User{})
repo := user.NewRepository(db.DB())
// test repository methods...

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Equal

func Equal[T comparable](t *testing.T, want, got T)

Equal fails the test if got != want.

func NewTestDB

func NewTestDB(t *testing.T, models ...any) *database.DB

NewTestDB creates a SQLite in-memory *database.DB and auto-migrates the provided models. The database is isolated per test — each call creates a fresh DB.

db := testkit.NewTestDB(t, &user.User{})
repo := user.NewRepository(db.DB())

func NoError

func NoError(t *testing.T, err error)

NoError fails the test if err is not nil.

func Table

func Table(t *testing.T, cases []Case)

Table runs a slice of Cases as subtests via t.Run.

testkit.Table(t, []testkit.Case{
    {Name: "success", Run: func(t *testing.T) { ... }},
    {Name: "not found", Run: func(t *testing.T) { ... }},
})

func True

func True(t *testing.T, condition bool, msg string)

True fails the test if condition is false.

Types

type Case

type Case struct {
	Name string
	Run  func(t *testing.T)
}

Case represents a single table-driven test case.

type HTTPSuite

type HTTPSuite struct {
	// contains filtered or unexported fields
}

HTTPSuite wraps a gin.Engine for ergonomic HTTP testing.

func NewHTTPSuite

func NewHTTPSuite(t *testing.T, router *gin.Engine) *HTTPSuite

NewHTTPSuite creates a new HTTPSuite for the given router.

func (*HTTPSuite) DELETE

func (s *HTTPSuite) DELETE(path string) *requestBuilder

DELETE starts a DELETE request builder.

func (*HTTPSuite) GET

func (s *HTTPSuite) GET(path string) *requestBuilder

GET starts a GET request builder.

func (*HTTPSuite) PATCH

func (s *HTTPSuite) PATCH(path, body string) *requestBuilder

PATCH starts a PATCH request builder with a JSON body.

func (*HTTPSuite) POST

func (s *HTTPSuite) POST(path, body string) *requestBuilder

POST starts a POST request builder with a JSON body.

type Response

type Response struct {
	// contains filtered or unexported fields
}

Response holds the HTTP test response and provides assertion methods.

func (*Response) Body

func (r *Response) Body() []byte

Body returns the raw response body bytes.

func (*Response) Code

func (r *Response) Code() int

Code returns the HTTP status code.

func (*Response) ExpectJSONPath

func (r *Response) ExpectJSONPath(path string, want any) *Response

ExpectJSONPath asserts that the JSON path in the response body equals the expected value. Uses simple dot-notation paths ($.field or $.nested.field or $.field[0]).

func (*Response) ExpectStatus

func (r *Response) ExpectStatus(code int) *Response

ExpectStatus asserts the HTTP status code matches the expected value.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL