testing

package
v1.16.0 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AssertDatabaseCount

func AssertDatabaseCount(t testing.TB, db *lucid.DB, table string, expected int64, conditions map[string]any)

AssertDatabaseCount asserts the table has exactly n records (optionally matching conditions).

nimbustesting.AssertDatabaseCount(t, db, "users", 5, nil)
nimbustesting.AssertDatabaseCount(t, db, "users", 2, map[string]any{"role": "admin"})

func AssertDatabaseHas

func AssertDatabaseHas(t testing.TB, db *lucid.DB, table string, conditions map[string]any)

AssertDatabaseHas asserts that a record matching the given conditions exists in the specified table. Conditions is a map[string]any of column=value pairs.

nimbustesting.AssertDatabaseHas(t, db, "users", map[string]any{"email": "alice@example.com"})

func AssertDatabaseMissing

func AssertDatabaseMissing(t testing.TB, db *lucid.DB, table string, conditions map[string]any)

AssertDatabaseMissing asserts that no record matching the given conditions exists in the specified table.

nimbustesting.AssertDatabaseMissing(t, db, "users", map[string]any{"email": "deleted@example.com"})

func AssertDispatched added in v1.15.0

func AssertDispatched[T queue.Job](t testing.TB, f *FakeQueue, match ...func(T) bool)

AssertDispatched fails the test unless a job of type T was dispatched (and, when match is given, one of them matches it).

func AssertModelExists

func AssertModelExists(t testing.TB, db *lucid.DB, model any)

AssertModelExists asserts that the given GORM model exists in the database.

func AssertModelMissing

func AssertModelMissing(t testing.TB, db *lucid.DB, model any)

AssertModelMissing asserts that the given GORM model does NOT exist.

func AssertNotDispatched added in v1.15.0

func AssertNotDispatched[T queue.Job](t testing.TB, f *FakeQueue, match ...func(T) bool)

AssertNotDispatched fails the test if a job of type T was dispatched (that matches match, when given).

func AssertNotSoftDeleted

func AssertNotSoftDeleted(t testing.TB, db *lucid.DB, table string, conditions map[string]any)

AssertNotSoftDeleted asserts that a record exists and is NOT soft-deleted.

func AssertNotificationNotSent added in v1.15.0

func AssertNotificationNotSent[T notification.Notification](t testing.TB, f *FakeNotifier)

AssertNotificationNotSent fails the test if a notification of type T was sent.

func AssertNotificationSent added in v1.15.0

func AssertNotificationSent[T notification.Notification](t testing.TB, f *FakeNotifier, match ...func(T) bool)

AssertNotificationSent fails the test unless a notification of type T was sent (and, when match is given, one of them matches it).

func AssertSoftDeleted

func AssertSoftDeleted(t testing.TB, db *lucid.DB, table string, conditions map[string]any)

AssertSoftDeleted asserts that a soft-deleted record exists in the table (i.e., deleted_at IS NOT NULL).

func AssertStatus

func AssertStatus(w *httptest.ResponseRecorder, want int) bool

AssertStatus is a legacy helper (use TestResponse assertions instead).

func JobsOf added in v1.15.0

func JobsOf[T queue.Job](f *FakeQueue) []T

JobsOf returns the dispatched jobs of type T (for example *SendWelcome), decoded from what was queued.

func NotificationsOf added in v1.15.0

func NotificationsOf[T notification.Notification](f *FakeNotifier) []T

NotificationsOf returns the sent notifications of type T.

func RefreshDatabase

func RefreshDatabase(t testing.TB, db *lucid.DB) *lucid.DB

RefreshDatabase wraps a test in a database transaction that is rolled back after the test completes. This ensures each test starts with a clean database state without running migrations.

Usage:

func TestCreateUser(t *testing.T) {
    tx := nimbustesting.RefreshDatabase(t, db)
    // use tx instead of db in your test
    tx.Create(&User{Name: "Alice"})
    // transaction is automatically rolled back when test ends
}

func SeedDatabase

func SeedDatabase(db *lucid.DB, seeder func(db *lucid.DB) error) error

SeedDatabase runs a seeder function within test scope. The seeder receives a *lucid.DB (which could be a transaction).

func TruncateTables

func TruncateTables(db *lucid.DB, tables ...string) error

TruncateTables truncates the given table names. Useful for test setup when RefreshDatabase (transaction-per-test) is not suitable.

Types

type DispatchedEvent added in v1.15.0

type DispatchedEvent struct {
	Name    string
	Payload any
}

DispatchedEvent records one Dispatch or DispatchAsync call.

type DispatchedJob

type DispatchedJob struct {
	Job   queue.Job // nil when the job type was not registered (see FakeJobs)
	Queue string
	Delay time.Duration
	// Payload is what a real adapter would have stored; nil for jobs
	// recorded with Push or PushToQueue.
	Payload *queue.JobPayload
}

DispatchedJob records a job that was dispatched.

type FakeCacheStore added in v1.15.0

type FakeCacheStore struct {
	*cache.MemoryStore
}

FakeCacheStore is the empty in-memory store FakeCache installs.

func FakeCache added in v1.15.0

func FakeCache(t testing.TB) *FakeCacheStore

FakeCache gives the cache package helpers (cache.Get, cache.Remember, ...) an empty in-memory store for the rest of the test, so values cached by one test never reach another, then restores the previous global store.

func (*FakeCacheStore) AssertHas added in v1.15.0

func (f *FakeCacheStore) AssertHas(t testing.TB, key string)

AssertHas fails the test unless key is cached.

func (*FakeCacheStore) AssertMissing added in v1.15.0

func (f *FakeCacheStore) AssertMissing(t testing.TB, key string)

AssertMissing fails the test if key is cached.

type FakeDisk added in v1.15.0

type FakeDisk struct {
	*storage.MemoryDriver
}

FakeDisk is an in-memory storage.Driver with test assertions.

func FakeStorage added in v1.15.0

func FakeStorage(t testing.TB) *FakeDisk

FakeStorage returns an empty in-memory disk. Storage has no global driver, so pass it wherever the code under test takes a storage.Driver.

disk := nimbustesting.FakeStorage(t)
app.Uploads = disk
client.Post("/avatar", body)
disk.AssertExists(t, "avatars/1.png")

func (*FakeDisk) AssertCount added in v1.15.0

func (d *FakeDisk) AssertCount(t testing.TB, n int)

AssertCount fails the test unless exactly n files are stored.

func (*FakeDisk) AssertExists added in v1.15.0

func (d *FakeDisk) AssertExists(t testing.TB, path string)

AssertExists fails the test unless a file is stored at path.

func (*FakeDisk) AssertMissing added in v1.15.0

func (d *FakeDisk) AssertMissing(t testing.TB, path string)

AssertMissing fails the test if a file is stored at path.

func (*FakeDisk) Contents added in v1.15.0

func (d *FakeDisk) Contents(t testing.TB, path string) []byte

Contents returns the stored bytes at path, failing the test if it is missing.

type FakeEventBus added in v1.15.0

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

FakeEventBus records the events a faked dispatcher received.

func FakeEvents added in v1.15.0

func FakeEvents(t testing.TB, except ...string) *FakeEventBus

FakeEvents fakes events.Default for the rest of the test: events.Dispatch records events instead of running listeners, except for the event names in except, whose listeners still run (they are recorded too).

bus := nimbustesting.FakeEvents(t)
client.PostJSON("/signup", body)
bus.AssertDispatched(t, "user.created")

func FakeEventsOn added in v1.15.0

func FakeEventsOn(t testing.TB, d *events.Dispatcher, except ...string) *FakeEventBus

FakeEventsOn fakes one dispatcher, such as app.Events, the same way FakeEvents fakes events.Default.

func (*FakeEventBus) AssertDispatched added in v1.15.0

func (f *FakeEventBus) AssertDispatched(t testing.TB, event string, match ...func(payload any) bool)

AssertDispatched fails the test unless event was dispatched (and, when match is given, one of its payloads matches it).

func (*FakeEventBus) AssertDispatchedTimes added in v1.15.0

func (f *FakeEventBus) AssertDispatchedTimes(t testing.TB, event string, n int)

AssertDispatchedTimes fails the test unless event was dispatched exactly n times.

func (*FakeEventBus) AssertNotDispatched added in v1.15.0

func (f *FakeEventBus) AssertNotDispatched(t testing.TB, event string)

AssertNotDispatched fails the test if event was dispatched.

func (*FakeEventBus) AssertNothingDispatched added in v1.15.0

func (f *FakeEventBus) AssertNothingDispatched(t testing.TB)

AssertNothingDispatched fails the test if any event was dispatched.

func (*FakeEventBus) Dispatched added in v1.15.0

func (f *FakeEventBus) Dispatched() []DispatchedEvent

Dispatched returns every recorded event, in order.

func (*FakeEventBus) Payloads added in v1.15.0

func (f *FakeEventBus) Payloads(event string) []any

Payloads returns the payloads recorded for event, in order.

type FakeMailer

type FakeMailer struct {
	Mails []*mail.Message
	// contains filtered or unexported fields
}

FakeMailer captures sent emails for testing assertions. Implements mail.Driver.

func FakeMail added in v1.15.0

func FakeMail(t testing.TB) *FakeMailer

FakeMail makes mail.Send (and notifications' mail channel) capture messages on a fresh FakeMailer for the rest of the test, then restores mail.Default.

mails := nimbustesting.FakeMail(t)
client.PostJSON("/signup", body)
mails.AssertSent(t, func(m *mail.Message) bool { return m.Subject == "Welcome" })

func NewFakeMailer

func NewFakeMailer() *FakeMailer

NewFakeMailer returns a fresh fake mailer.

func (*FakeMailer) AssertNothingSent added in v1.15.0

func (f *FakeMailer) AssertNothingSent(t testing.TB)

AssertNothingSent fails the test if any message was sent.

func (*FakeMailer) AssertSent added in v1.15.0

func (f *FakeMailer) AssertSent(t testing.TB, match ...func(*mail.Message) bool)

AssertSent fails the test unless a message was sent (and, when match is given, one of them matches it).

func (*FakeMailer) AssertSentCount added in v1.15.0

func (f *FakeMailer) AssertSentCount(t testing.TB, n int)

AssertSentCount fails the test unless exactly n messages were sent.

func (*FakeMailer) AssertSentTo added in v1.15.0

func (f *FakeMailer) AssertSentTo(t testing.TB, addr string)

AssertSentTo fails the test unless a message was sent to addr.

func (*FakeMailer) HasSentTo

func (f *FakeMailer) HasSentTo(addr string) bool

HasSentTo returns true if any mail was sent to the given address.

func (*FakeMailer) Reset

func (f *FakeMailer) Reset()

Reset clears all captured messages.

func (*FakeMailer) Send

func (f *FakeMailer) Send(m *mail.Message) error

Send captures the message instead of sending it.

func (*FakeMailer) Sent

func (f *FakeMailer) Sent() []*mail.Message

Sent returns all captured messages.

func (*FakeMailer) SentCount

func (f *FakeMailer) SentCount() int

SentCount returns how many emails were sent.

func (*FakeMailer) SentTo

func (f *FakeMailer) SentTo(addr string) []*mail.Message

SentTo returns all messages sent to the given email address.

type FakeNotifier added in v1.15.0

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

FakeNotifier records the notifications sent while faked.

func FakeNotifications added in v1.15.0

func FakeNotifications(t testing.TB) *FakeNotifier

FakeNotifications makes notification.Send (and SendMail, Broadcast) record notifications instead of mailing or broadcasting them for the rest of the test. AfterSend hooks still run for Send.

notes := nimbustesting.FakeNotifications(t)
client.PostJSON("/orders", body)
nimbustesting.AssertNotificationSent(t, notes, func(n *OrderShipped) bool { return n.OrderID == 7 })

func (*FakeNotifier) AssertNothingSent added in v1.15.0

func (f *FakeNotifier) AssertNothingSent(t testing.TB)

AssertNothingSent fails the test if any notification was sent.

func (*FakeNotifier) AssertSentCount added in v1.15.0

func (f *FakeNotifier) AssertSentCount(t testing.TB, n int)

AssertSentCount fails the test unless exactly n notifications were sent.

func (*FakeNotifier) Sent added in v1.15.0

Sent returns every recorded notification, in order.

type FakeQueue

type FakeQueue struct {
	Jobs []DispatchedJob
	// contains filtered or unexported fields
}

FakeQueue captures dispatched jobs instead of processing them.

func FakeJobs added in v1.15.0

func FakeJobs(t testing.TB) *FakeQueue

FakeJobs sends every queue.Dispatch to a fresh FakeQueue for the rest of the test and puts the previous global manager back when it ends. Jobs are serialized as a real adapter would store them, so a job that cannot be marshaled fails at Dispatch.

Job types registered with queue.Register (after FakeJobs, or on the manager it replaced) come back as values in Dispatched and run with ProcessAll. JobsOf and AssertDispatched decode any job type without registering it.

jobs := nimbustesting.FakeJobs(t)
client.PostJSON("/signup", body)
nimbustesting.AssertDispatched(t, jobs, func(j *SendWelcome) bool { return j.Email == "a@b.co" })

func NewFakeQueue

func NewFakeQueue() *FakeQueue

NewFakeQueue returns a fresh fake queue. Use FakeJobs to also capture queue.Dispatch calls.

func (*FakeQueue) AssertDispatchedCount added in v1.15.0

func (f *FakeQueue) AssertDispatchedCount(t testing.TB, n int)

AssertDispatchedCount fails the test unless exactly n jobs were dispatched.

func (*FakeQueue) AssertNothingDispatched added in v1.15.0

func (f *FakeQueue) AssertNothingDispatched(t testing.TB)

AssertNothingDispatched fails the test if any job was dispatched.

func (*FakeQueue) Dispatched

func (f *FakeQueue) Dispatched() []DispatchedJob

Dispatched returns all captured jobs.

func (*FakeQueue) DispatchedCount

func (f *FakeQueue) DispatchedCount() int

DispatchedCount returns how many jobs were dispatched.

func (*FakeQueue) ProcessAll

func (f *FakeQueue) ProcessAll(ctx context.Context) []error

ProcessAll runs all captured jobs synchronously (useful for testing side effects).

func (*FakeQueue) Push

func (f *FakeQueue) Push(job queue.Job)

Push captures the job with an empty queue name.

func (*FakeQueue) PushToQueue

func (f *FakeQueue) PushToQueue(queueName string, job queue.Job)

PushToQueue captures the job with the specified queue name.

func (*FakeQueue) Reset

func (f *FakeQueue) Reset()

Reset clears all captured jobs.

type FakeRoute added in v1.15.0

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

FakeRoute is one stub added with FakeTransport.On.

func (*FakeRoute) Fail added in v1.15.0

func (r *FakeRoute) Fail(err error) *FakeRoute

Fail makes matching requests fail with err, like a network error.

func (*FakeRoute) Hits added in v1.15.0

func (r *FakeRoute) Hits() int

Hits returns how many requests this stub answered.

func (*FakeRoute) Respond added in v1.15.0

func (r *FakeRoute) Respond(status int, body string, headers ...string) *FakeRoute

Respond answers with status and body. headers are key, value pairs.

func (*FakeRoute) RespondJSON added in v1.15.0

func (r *FakeRoute) RespondJSON(status int, v any) *FakeRoute

RespondJSON answers with status and v encoded as JSON.

func (*FakeRoute) RespondWith added in v1.15.0

func (r *FakeRoute) RespondWith(fn func(*http.Request) (*http.Response, error)) *FakeRoute

RespondWith answers with whatever fn returns.

type FakeTransport added in v1.15.0

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

FakeTransport answers outgoing HTTP requests from canned responses.

func FakeHTTP added in v1.15.0

func FakeHTTP(t testing.TB) *FakeTransport

FakeHTTP replaces http.DefaultTransport for the rest of the test, so every client without a transport of its own (http.DefaultClient, &http.Client{...}) gets answers from On stubs instead of the network. A request no stub matches fails the test and returns an error, unless AllowStray was called.

Clients that set their own Transport are not intercepted, nor are clients that copied DefaultTransport before FakeHTTP ran. For the AI providers use ai.Fake instead.

api := nimbustesting.FakeHTTP(t)
api.On("POST", "https://api.stripe.com/v1/charges").RespondJSON(200, map[string]any{"id": "ch_1"})
client.PostJSON("/checkout", body)
api.AssertSent(t, func(r nimbustesting.RecordedRequest) bool { return r.URL.Path == "/v1/charges" })

func (*FakeTransport) AllowStray added in v1.15.0

func (f *FakeTransport) AllowStray() *FakeTransport

AllowStray lets requests no stub matches go to the real network.

func (*FakeTransport) AssertNothingSent added in v1.15.0

func (f *FakeTransport) AssertNothingSent(t testing.TB)

AssertNothingSent fails the test if any request was sent.

func (*FakeTransport) AssertSent added in v1.15.0

func (f *FakeTransport) AssertSent(t testing.TB, match ...func(RecordedRequest) bool)

AssertSent fails the test unless a request was sent (and, when match is given, one of them matches it).

func (*FakeTransport) AssertSentCount added in v1.15.0

func (f *FakeTransport) AssertSentCount(t testing.TB, n int)

AssertSentCount fails the test unless exactly n requests were sent.

func (*FakeTransport) On added in v1.15.0

func (f *FakeTransport) On(method, pattern string) *FakeRoute

On stubs requests whose method and URL match. method "" or "*" matches any method. In pattern, * matches any run of characters; a pattern without a scheme matches host and path ("api.stripe.com/v1/*"), and the query string is ignored unless the pattern has one. When several stubs match, the most recently added wins. A stub answers 200 with an empty body until told otherwise.

func (*FakeTransport) Requests added in v1.15.0

func (f *FakeTransport) Requests() []RecordedRequest

Requests returns every request sent, in order.

func (*FakeTransport) RoundTrip added in v1.15.0

func (f *FakeTransport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper.

type RecordedRequest added in v1.15.0

type RecordedRequest struct {
	Method string
	URL    *url.URL
	Header http.Header
	Body   []byte
}

RecordedRequest is one outgoing request seen by FakeHTTP.

func (RecordedRequest) JSON added in v1.15.0

func (r RecordedRequest) JSON(v any) error

JSON decodes the request body into v.

type TestClient

type TestClient struct {
	Router *router.Router
	// contains filtered or unexported fields
}

TestClient performs HTTP requests against a Nimbus router.

func New added in v1.4.0

func New(app *nimbus.App) *TestClient

New returns an HTTP test client bound to the given Nimbus App. It automatically warms up the application if not already warmed.

func NewAppTestClient

func NewAppTestClient(setup func(app *nimbus.App)) (*nimbus.App, *TestClient)

NewAppTestClient creates a minimal Nimbus application with a fresh router and returns both the app and an HTTP TestClient bound to its router.

func NewTestClient

func NewTestClient(r *router.Router) *TestClient

NewTestClient returns a client that sends requests to the given router.

func (*TestClient) Delete

func (c *TestClient) Delete(path string) *TestResponse

Delete performs a DELETE request.

func (*TestClient) Do

func (c *TestClient) Do(req *http.Request) *TestResponse

Do executes a raw *http.Request and returns a TestResponse.

func (*TestClient) Get

func (c *TestClient) Get(path string) *TestResponse

Get performs a GET request and returns a TestResponse.

func (*TestClient) Patch

func (c *TestClient) Patch(path string, body []byte) *TestResponse

Patch performs a PATCH request.

func (*TestClient) Post

func (c *TestClient) Post(path string, body []byte) *TestResponse

Post performs a POST request with an optional JSON body.

func (*TestClient) PostForm

func (c *TestClient) PostForm(path string, data url.Values) *TestResponse

PostForm posts form data.

func (*TestClient) PostJSON

func (c *TestClient) PostJSON(path string, v any) *TestResponse

PostJSON posts a JSON-serializable value.

func (*TestClient) Put

func (c *TestClient) Put(path string, body []byte) *TestResponse

Put performs a PUT request.

func (*TestClient) PutJSON

func (c *TestClient) PutJSON(path string, v any) *TestResponse

PutJSON puts a JSON-serializable value.

func (*TestClient) WithBearerToken

func (c *TestClient) WithBearerToken(token string) *TestClient

WithBearerToken sets the Authorization header.

func (*TestClient) WithCookie

func (c *TestClient) WithCookie(cookie *http.Cookie) *TestClient

WithCookie adds a cookie for all subsequent requests.

func (*TestClient) WithHeader

func (c *TestClient) WithHeader(key, value string) *TestClient

WithHeader sets a header for all subsequent requests.

type TestResponse

type TestResponse struct {
	*httptest.ResponseRecorder
}

TestResponse wraps httptest.ResponseRecorder with assertion helpers.

func (*TestResponse) AssertContains

func (r *TestResponse) AssertContains(t testing.TB, substr string) *TestResponse

AssertContains fails t if body does not contain substr.

func (*TestResponse) AssertCreated

func (r *TestResponse) AssertCreated(t testing.TB) *TestResponse

AssertCreated asserts 201.

func (*TestResponse) AssertForbidden

func (r *TestResponse) AssertForbidden(t testing.TB) *TestResponse

AssertForbidden asserts 403.

func (*TestResponse) AssertHeader

func (r *TestResponse) AssertHeader(t testing.TB, key, want string) *TestResponse

AssertHeader asserts a response header value.

func (*TestResponse) AssertJSON

func (r *TestResponse) AssertJSON(t testing.TB, v any) *TestResponse

AssertJSON decodes the response body as JSON into v.

func (*TestResponse) AssertJSONPath

func (r *TestResponse) AssertJSONPath(t testing.TB, key string, want any) *TestResponse

AssertJSONPath asserts that a JSON object has the given key with the given value.

func (*TestResponse) AssertNoContent

func (r *TestResponse) AssertNoContent(t testing.TB) *TestResponse

AssertNoContent asserts 204.

func (*TestResponse) AssertNotFound

func (r *TestResponse) AssertNotFound(t testing.TB) *TestResponse

AssertNotFound asserts 404.

func (*TestResponse) AssertOK

func (r *TestResponse) AssertOK(t testing.TB) *TestResponse

AssertOK asserts 200.

func (*TestResponse) AssertRedirect

func (r *TestResponse) AssertRedirect(t testing.TB, location string) *TestResponse

AssertRedirect asserts a 3xx response with the given Location header.

func (*TestResponse) AssertStatus

func (r *TestResponse) AssertStatus(t testing.TB, want int) *TestResponse

AssertStatus fails t if the status code does not match.

func (*TestResponse) AssertUnauthorized

func (r *TestResponse) AssertUnauthorized(t testing.TB) *TestResponse

AssertUnauthorized asserts 401.

Directories

Path Synopsis
Package browser is a Dusk-style end-to-end testing harness for Nimbus.
Package browser is a Dusk-style end-to-end testing harness for Nimbus.

Jump to

Keyboard shortcuts

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