Testing
irgo provides testing utilities to help you test your handlers and templates.
Test Client
The testing package provides an HTTP client for testing handlers:
import ( "testing" irgotest "github.com/stukennedy/irgo/pkg/testing")func TestListTodos(t *testing.T) { r := app.NewRouter() client := irgotest.NewClient(r.Handler()) resp := client.Get("/todos") resp.AssertOK(t) resp.AssertContains(t, "My Todos")}HTTP Methods
client := irgotest.NewClient(handler)// GET requestresp := client.Get("/users")// GET with query parametersresp := client.Get("/search?q=hello")// POST with form dataresp := client.PostForm("/users", map[string]string{ "name": "John", "email": "john@example.com",})// POST with JSONresp := client.PostJSON("/api/users", map[string]any{ "name": "John", "email": "john@example.com",})// PUT requestresp := client.Put("/users/123", map[string]string{ "name": "Jane",})// PATCH requestresp := client.Patch("/users/123", map[string]string{ "name": "Jane",})// DELETE requestresp := client.Delete("/users/123")Assertions
resp := client.Get("/users")// Status assertionsresp.AssertOK(t) // 200resp.AssertStatus(t, 201) // Specific statusresp.AssertRedirect(t, "/login") // 3xx redirect// Content assertionsresp.AssertContains(t, "Welcome")resp.AssertNotContains(t, "Error")// Header assertionsresp.AssertHeader(t, "Content-Type", "text/html")// Get response databody := resp.Body() // stringstatus := resp.StatusCode // intTesting HTMX Requests
func TestHTMXRequest(t *testing.T) { client := irgotest.NewClient(handler) // Simulate HTMX request resp := client.GetWithHeaders("/users", map[string]string{ "HX-Request": "true", "HX-Target": "#user-list", }) resp.AssertOK(t) // Should return fragment, not full page resp.AssertNotContains(t, "<!DOCTYPE html>") resp.AssertContains(t, "<div class="user-card">")}Testing Handlers Directly
func TestCreateUser(t *testing.T) { // Create mock context ctx := irgotest.NewContext() ctx.SetFormValue("name", "John") ctx.SetFormValue("email", "john@example.com") // Call handler html, err := handlers.CreateUser(ctx) if err != nil { t.Fatalf("unexpected error: %v", err) } if !strings.Contains(html, "John") { t.Error("expected response to contain user name") }}Testing Templates
func TestUserCard(t *testing.T) { user := User{ ID: "123", Name: "John", Email: "john@example.com", } renderer := render.NewTemplRenderer() html, err := renderer.Render(templates.UserCard(user)) if err != nil { t.Fatalf("render error: %v", err) } if !strings.Contains(html, "John") { t.Error("expected card to contain user name") } if !strings.Contains(html, "john@example.com") { t.Error("expected card to contain email") }}Running Tests
# Run all testsgo test ./...# Run with verbose outputgo test -v ./...# Run specific packagego test ./handlers/...# Run with coveragego test -cover ./...Example Test File
handlers/todos_test.go
package handlersimport ( "testing" "myapp/app" irgotest "github.com/stukennedy/irgo/pkg/testing")func TestTodoWorkflow(t *testing.T) { r := app.NewRouter() client := irgotest.NewClient(r.Handler()) // List todos (empty) resp := client.Get("/todos") resp.AssertOK(t) resp.AssertContains(t, "No todos yet") // Create todo resp = client.PostForm("/todos", map[string]string{ "title": "Buy groceries", }) resp.AssertOK(t) resp.AssertContains(t, "Buy groceries") // Toggle todo resp = client.PostForm("/todos/1/toggle", nil) resp.AssertOK(t) resp.AssertContains(t, "completed") // Delete todo resp = client.Delete("/todos/1") resp.AssertOK(t)}Next Steps
- Routing & Handlers - Handler API reference
- Templ Templates - Template testing
