-
Notifications
You must be signed in to change notification settings - Fork 0
Testing
MeGaNeKo edited this page Mar 20, 2026
·
1 revision
neomatest.New creates an in-memory API using the built-in flow adapter. No HTTP server is started.
import (
"github.com/MeGaNeKoS/neoma/neomatest"
"github.com/MeGaNeKoS/neoma/neoma"
)
_, api := neomatest.New(t)Pass a custom config if needed:
config := neoma.DefaultConfig("Test API", "1.0.0")
config.RejectUnknownQueryParameters = true
_, api := neomatest.New(t, config)neomatest.Wrap wraps an existing core.API for testing:
api := neomatest.Wrap(t, existingAPI)TestAPI embeds core.API and adds two methods:
type TestAPI interface {
core.API
Do(method, path string, args ...any) *httptest.ResponseRecorder
DoCtx(ctx context.Context, method, path string, args ...any) *httptest.ResponseRecorder
}Do and DoCtx are the only request methods. DoCtx accepts a context.Context as the first argument; Do uses context.Background().
Variable args accept three types in any order:
-
stringin"Header-Name: value"format sets a request header. -
io.Readeris used as the raw request body. -
struct,map, orsliceis JSON-encoded and sent withContent-Type: application/json.
package myapi_test
import (
"context"
"encoding/json"
"testing"
"github.com/MeGaNeKoS/neoma/core"
"github.com/MeGaNeKoS/neoma/neoma"
"github.com/MeGaNeKoS/neoma/neomatest"
"github.com/stretchr/testify/assert"
)
type CreateInput struct {
Body struct {
Name string `json:"name" minLength:"1"`
}
}
type CreateOutput struct {
Body struct {
ID int `json:"id"`
Name string `json:"name"`
}
}
func createHandler(ctx context.Context, input *CreateInput) (*CreateOutput, error) {
resp := &CreateOutput{}
resp.Body.ID = 1
resp.Body.Name = input.Body.Name
return resp, nil
}
func TestCreate(t *testing.T) {
_, api := neomatest.New(t)
neoma.Post(api, "/items", createHandler)
// Success
resp := api.Do("POST", "/items", map[string]any{"name": "Widget"})
assert.Equal(t, 200, resp.Code)
var body struct {
ID int `json:"id"`
Name string `json:"name"`
}
json.Unmarshal(resp.Body.Bytes(), &body)
assert.Equal(t, "Widget", body.Name)
// Validation error
resp = api.Do("POST", "/items", map[string]any{"name": ""})
assert.Equal(t, 422, resp.Code)
// With custom headers and context
resp = api.DoCtx(context.Background(), "POST", "/items",
"Authorization: Bearer token",
map[string]any{"name": "Gadget"},
)
assert.Equal(t, 200, resp.Code)
}For testing handlers or middleware that need a core.Context directly:
import "github.com/MeGaNeKoS/neoma/neomatest"
op := &core.Operation{Method: "GET", Path: "/test"}
req := httptest.NewRequest("GET", "/test", nil)
w := httptest.NewRecorder()
ctx := neomatest.NewContext(op, req, w)