zentests

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2026 License: MIT Imports: 12 Imported by: 0

README

zentests

Readable Go tests without magic. Inspired by RSpec/Pest

zentests provides fluent, chainable HTTP testing for Fiber applications with RSpec-style syntax.

Go Report Card GoDoc

Why zentests?

  • No magic: Standard Go testing, no reflection tricks
  • Type safe: Strict assertions catch bugs early
  • Fiber-native: Built for Fiber, not adapted from net/http
  • Chainable: Readable, expressive test code
  • Familiar: RSpec/Pest-inspired syntax
  • Well-tested: 98.2% code coverage
Why only Fiber support?

Simple. I'm using Fiber for my projects and created these tests to make working on my projects faster.

You are welcome to create a version with support for your preferred routing package.


Installation

go get github.com/kematzy/zentests

Requirements:

  • Go 1.25 or higher
  • Fiber v3.x

Fiber v2 Users: If you're using Fiber v2, use the fiber-v2 branch:

go get github.com/kematzy/zentests@fiber-v2

See Branches for more information.


Branches

Branch Fiber Version Go Version Status
master v3.x 1.25+ Active development
fiber-v2 v2.x 1.21+ Maintenance only

The fiber-v2 branch receives bug fixes and security updates only. New features are developed on master (Fiber v3).

Migrating from Fiber v2 to v3

If you're upgrading from Fiber v2 to v3, see the upgrade guide.


Quick Start

package myapp_test

import (
    "testing"
    "github.com/gofiber/fiber/v3"
    "github.com/kematzy/zentests"
)

func TestAPI(t *testing.T) {
    zt := zentests.New(t)
    app := fiber.New()
    
    // Your routes here...
    // Note: Fiber v3 uses fiber.Ctx (interface), not *fiber.Ctx (pointer)
    app.Get("/api/health", func(c fiber.Ctx) error {
        return c.JSON(fiber.Map{"status": "ok"})
    })
    
    // Fluent, chainable assertions
    zt.Get(app, "/api/health").
        OK().
        IsJSON().
        Has("status", "ok")
}

Code Quality & Coverage

Coverage: 98.2% of statements

All functions are fully documented with comprehensive examples. See our test coverage report for details.


Examples

The examples/ directory contains practical examples demonstrating different testing styles:

flat_style.go - Simple Testing

Demonstrates simple, flat-style testing without suites. Perfect for quick API tests.

// Simple, no suite overhead
zt.Get(app, "/api/health").OK().IsJSON().Has("status", "ok")

zt.PostJSON(app, "/api/users", userData).
    Created().
    Has("id", float64(1)).
    Has("name", "John Doe")
routes.go - JSON Testing

Shows comprehensive JSON assertions with dot notation for nested objects and arrays.

zt.Get(app, "/api/users").
    OK().
    IsJSON().
    Has("success", true).
    Has("data.count", 2).
    ArrayLength("data.users", 2).
    Has("data.users.0.name", "John") // dot notation
suite.go - BDD Style Testing

Demonstrates BDD-style testing with Describe, It, and lifecycle hooks (BeforeEach, AfterEach).

zt.Describe("User API", func(ctx *zentests.SuiteContext) {
    ctx.
        BeforeEach(func(zt *zentests.T) {
            // Fresh app for each test
            app = fiber.New()
            SetupRoutes(app)
        }).
        AfterEach(func(zt *zentests.T) {
            // Cleanup
            app.Shutdown()
        })

    ctx.It("returns user list", func(zt *zentests.T) {
        zt.Get(app, "/api/users").
            OK().
            IsJSON().
            ArrayLength("data.users", 2)
    })
})

Features

HTTP Methods

All methods accept *fiber.App and path, return *Response for chaining:

Method Description
Get(app, path) GET request
Post(app, path, body) POST with raw body
PostJSON(app, path, data) POST with JSON body
PostForm(app, path, data) POST with form data
Put(app, path, body) PUT request
PutJSON(app, path, data) PUT with JSON
Patch(app, path, body) PATCH request
PatchJSON(app, path, data) PATCH with JSON
Delete(app, path) DELETE request
DeleteJSON(app, path, data) DELETE with JSON body
HTTP Methods with TestConfig (Fiber v3+)

For custom timeout and behavior control, use the *WithConfig variants:

Method Description
GetWithConfig(app, path, cfg) GET with custom TestConfig
PostWithConfig(app, path, body, cfg) POST with custom TestConfig
PostJSONWithConfig(app, path, data, cfg) POST JSON with custom TestConfig
PostFormWithConfig(app, path, data, cfg) POST form with custom TestConfig
PutWithConfig(app, path, body, cfg) PUT with custom TestConfig
PutJSONWithConfig(app, path, data, cfg) PUT JSON with custom TestConfig
PatchWithConfig(app, path, body, cfg) PATCH with custom TestConfig
PatchJSONWithConfig(app, path, data, cfg) PATCH JSON with custom TestConfig
DeleteWithConfig(app, path, cfg) DELETE with custom TestConfig
DeleteJSONWithConfig(app, path, data, cfg) DELETE JSON with custom TestConfig
TestConfig Usage
import (
    "time"
    "github.com/gofiber/fiber/v3"
    "github.com/kematzy/zentests"
)

func TestSlowEndpoint(t *testing.T) {
    zt := zentests.New(t)
    app := fiber.New()
    
    // Custom timeout for slow endpoints
    resp := zt.GetWithConfig(app, "/slow-endpoint", fiber.TestConfig{
        Timeout: 10 * time.Second,
    })
    resp.OK().IsJSON()
    
    // Custom timeout with FailOnTimeout behavior
    resp2 := zt.PostJSONWithConfig(app, "/api/users", userData, fiber.TestConfig{
        Timeout:       5 * time.Second,
        FailOnTimeout: true, // Returns error instead of partial response
    })
    resp2.Created()
}
TestConfig Options
Option Type Default Description
Timeout time.Duration 1s Request timeout duration
FailOnTimeout bool true Return error on timeout (true) or partial response (false)
Status Assertions
resp.OK()              // 200
resp.Created()         // 201
resp.Accepted()        // 202
resp.NoContent()       // 204
resp.BadRequest()      // 400
resp.Unauthorized()    // 401
resp.Forbidden()       // 403
resp.NotFound()        // 404
resp.Unprocessable()   // 422
resp.ServerError()     // 500
resp.Status(code)      // Custom status
Header Assertions
resp.HasHeader("X-Custom", "value")                                     // Exact match
resp.HeaderContains("X-Rate", "limit")                                  // Substring match
resp.HeaderPresent("X-Auth-Token")                                      // Header exists
resp.HeaderNotPresent("X-Auth-Token")                                   // Header does not exists
resp.HeaderHasValues("X-Features", []string{"audio", "video"})          // Header has multiple values
resp.CookieHasValues(map[string]string{"lang": "en", "theme": "dark"})  // Set-Cookie header test

// Content-Type Helpers
resp.HasContentType("text/html; charset=utf-8")                         // Checks Content-Type value

// Content-Type Shortcuts
resp.IsJSON()                                                           // Content-Type: application/json
resp.IsHTML()                                                           // Content-Type: text/html
resp.IsPlainText()                                                      // Content-Type: text/plain
resp.IsCSS()                                                            // Content-Type: text/css
resp.IsJS()                                                             // Content-Type: (application|text)/javascript
resp.IsXML()                                                            // Content-Type: (application|text)/xml
resp.IsImage()                                                          // Content-Type: image/*
resp.IsPNG()                                                            // Content-Type: image/png
resp.IsJPEG()                                                           // Content-Type: image/jpeg
resp.IsGIF()                                                            // Content-Type: image/gif
resp.IsSVG()                                                            // Content-Type: image/svg+xml
resp.IsWebP()                                                           // Content-Type: image/webp

// AJAX Detection:
resp.IsXHR()  // checks for "XMLHttpRequest" in X-Requested-With header
Body Assertions
resp.Contains("substring")             // Body contains text
resp.NotContains("substring")          // Body excludes text
resp.BodyMatches(`regex\d+`)           // Regex match
resp.Equals("exact body")              // Exact match
resp.IsEmpty()                         // Body is empty

JSON Assertions

Dot notation for nested keys: user.profile.name

resp.JSON()                            // Parse & cache JSON
resp.HasKey("user.name")               // Key exists
resp.Has("user.name", "John")          // Strict type match
resp.HasString("user.name", "John")    // String value
resp.HasInt("user.age", 30)            // Integer value (handles JSON float64)
resp.HasFloat("user.score", 9.5)       // Float value
resp.HasBool("user.active", true)      // Boolean value
resp.MatchesRegex("user.email", `[\w\.]+@`) // Regex match
resp.IsNull("user.deleted_at")         // Null check
resp.IsNotNull("user.id")              // Not null check
resp.ArrayLength("items", 3)           // Array length

// Bulk assertion
resp.Matches(map[string]any{
    "success": true,
    "data.count": 5,
    "data.user.name": "John",
})

BDD Style with Describe/It
func TestUserAPI(t *testing.T) {
    zt := zentests.New(t)
    
    zt.Describe("User API", func(ctx *zentests.SuiteContext) {
        var app *fiber.App
        
        ctx.BeforeEach(func(zt *zentests.T) {
            app = fiber.New()
            SetupRoutes(app)
        }).AfterEach(func(zt *zentests.T) {
            app.Shutdown()
        })
        
        ctx.It("lists users", func(zt *zentests.T) {
            zt.Get(app, "/users").
                OK().
                IsJSON().
                ArrayLength("data", 2)
        })
        
        ctx.It("creates user", func(zt *zentests.T) {
            zt.PostJSON(app, "/users", map[string]any{
                "name": "John",
            }).
                Created().
                Has("data.name", "John")
        })
    })
}

Type Safety

zentests enforces strict type checking:

// JSON numbers are float64 by default
resp.Has("count", 42)           // FAIL: 42 is int, JSON has float64
resp.HasInt("count", 42)        // PASS: handles conversion
resp.Has("count", float64(42))  // PASS: exact type match
resp.Has("count", 42.0)         // PASS: exact type match


Using with testify/suite

zentests integrates seamlessly with testify/suite for more complex test scenarios requiring suite-level setup/teardown.

Basic Structure
package myapp_test

import (
    "testing"
    "github.com/gofiber/fiber/v3"
    "github.com/kematzy/zentests"
    "github.com/stretchr/testify/suite"
)

// Define your suite struct
type UserAPISuite struct {
    suite.Suite
    app *fiber.App
    zt  *zentests.T
}

// SetupSuite runs ONCE before all tests in the suite
func (s *UserAPISuite) SetupSuite() {
    s.app = fiber.New()
    s.zt = zentests.New(s.T())  // Initialize zentests.T

    // Setup routes
    s.app.Get("/users", func(c fiber.Ctx) error {
        return c.JSON(fiber.Map{"users": []string{"John", "Jane"}})
    })

    s.app.Post("/users", func(c fiber.Ctx) error {
        return c.Status(201).JSON(fiber.Map{"id": 1, "name": "John"})
    })
}

// TearDownSuite runs ONCE after all tests in the suite
func (s *UserAPISuite) TearDownSuite() {
    // Cleanup resources (close database, etc.)
}

// SetupTest runs BEFORE EACH test
func (s *UserAPISuite) SetupTest() {
    // Reset state before each test
}

// TearDownTest runs AFTER EACH test
func (s *UserAPISuite) TearDownTest() {
    // Cleanup after each test
}

// Tests use the zentests.T instance
func (s *UserAPISuite) TestListUsers() {
    s.zt.Get(s.app, "/users").
        OK().
        IsJSON().
        ArrayLength("users", 2)
}

func (s *UserAPISuite) TestCreateUser() {
    s.zt.PostJSON(s.app, "/users", map[string]any{
        "name": "John",
    }).
        Created().
        Has("id", float64(1))
}

// Run the suite
func TestUserAPISuite(t *testing.T) {
    suite.Run(t, new(UserAPISuite))
}
Lifecycle Hooks Order
SetupSuite()           ← Runs once before all tests
    ├── TestA()
    │       ├── SetupTest()
    │       ├── [test code]
    │       └── TearDownTest()
    │
    └── TestB()
            ├── SetupTest()
            ├── [test code]
            └── TearDownTest()
TearDownSuite()        ← Runs once after all tests
Database Integration
type DatabaseSuite struct {
    suite.Suite
    app *fiber.App
    zt  *zentests.T
    db  *sql.DB  // or *gorm.DB
}

func (s *DatabaseSuite) SetupSuite() {
    // Connect to test database
    s.db, _ = sql.Open("sqlite3", ":memory:")

    s.app = fiber.New()
    s.zt = zentests.New(s.T())

    // Setup routes that use database
    s.app.Get("/users", func(c fiber.Ctx) error {
        var users []User
        s.db.Find(&users)
        return c.JSON(users)
    })
}

func (s *DatabaseSuite) SetupTest() {
    // Clean database before each test
    s.db.Exec("DELETE FROM users")
}

func (s *DatabaseSuite) TearDownSuite() {
    s.db.Close()
}
Multiple Suites with Shared Setup
// Base suite with common setup
type BaseSuite struct {
    suite.Suite
    App *fiber.App
    ZT  *zentests.T
}

func (s *BaseSuite) SetupSuite() {
    s.App = fiber.New()
    s.ZT = zentests.New(s.T())
}

// UserAPISuite inherits BaseSuite
type UserAPISuite struct {
    BaseSuite
}

func (s *UserAPISuite) SetupSuite() {
    s.BaseSuite.SetupSuite()
    // Add user-specific routes
    s.App.Get("/users", s.listUsers)
}

func TestUserAPISuite(t *testing.T) {
    suite.Run(t, new(UserAPISuite))
}
Using TestConfig with Suite
func (s *SlowAPISuite) TestSlowEndpoint() {
    // Use WithConfig for slow endpoints
    s.zt.GetWithConfig(s.app, "/slow-endpoint", fiber.TestConfig{
        Timeout: 10 * time.Second,
    }).OK()
}
Choosing Between zentests.Describe and testify/suite
Feature zentests.Describe testify/suite
Setup BeforeEach SetupTest
Teardown AfterEach TearDownTest
Suite setup Manual SetupSuite
Suite teardown Manual TearDownSuite
Parallel tests Limited Supported
Subtests It() s.Run()
Assertions zentests.T s.T() + s.zt
Best for Quick BDD tests Complex test setups

Migration from Fiber v2

If you're upgrading from Fiber v2 to v3, here are the key changes affecting zentests:

Import Path Change
// Fiber v2
import "github.com/gofiber/fiber/v2"

// Fiber v3
import "github.com/gofiber/fiber/v3"
Handler Signature Change

Fiber v3 uses fiber.Ctx as an interface (not a pointer):

// Fiber v2
app.Get("/route", func(c *fiber.Ctx) error {
    return c.SendString("hello")
})

// Fiber v3
app.Get("/route", func(c fiber.Ctx) error {
    return c.SendString("hello")
})
Body Parser Change

The BodyParser method has been replaced with the new Bind() API:

// Fiber v2
app.Post("/users", func(c *fiber.Ctx) error {
    var data map[string]any
    c.BodyParser(&data)
    return c.JSON(data)
})

// Fiber v3
app.Post("/users", func(c fiber.Ctx) error {
    var data map[string]any
    if err := c.Bind().Body(&data); err != nil {
        return err
    }
    return c.JSON(data)
})
New TestConfig Support

Fiber v3's app.Test() now accepts TestConfig instead of timeout duration:

// Fiber v2
resp, err := app.Test(req, 5*time.Second)

// Fiber v3
resp, err := app.Test(req) // Uses default 1s timeout
resp, err := app.Test(req, fiber.TestConfig{
    Timeout: 5 * time.Second,
})

zentests provides *WithConfig methods to expose this functionality:

// Fiber v2 style (still works)
zt.Get(app, "/route")

// Fiber v3 with custom timeout
zt.GetWithConfig(app, "/slow-route", fiber.TestConfig{
    Timeout: 10 * time.Second,
})

Development & Building

Make Commands
make help                   # Show this help message

# Testing
make test                   # Run all tests
make test-verbose           # Run all tests with verbose colored output
make test-coverage          # Run tests and generate coverage report

# Code Quality
make fmt                    # Format source code
make lint                   # Run linter
make tidy                   # Run tidy on Go modules
make vet                    # Run `go vet`

make modernize              # Run tool to identify & replace old Go code with newer standards.
make modernize-check        # Dry-run with diffs to identify old Go code with newer standards.

make check                  # Run all checks (fmt, vet, lint, check-test-coverage)
make check-test-coverage    # Run tests and enforce coverage threshold (default: 90%)

# Release
make release                # Release a new tagged version (e.g. make release VERSION=v1.2.3)
make release VERSION=v1.2.3 # Create specific version

# Development
make versions               # Show current and all versions
make git-push               # Push code to both repositories

# Documentation
make changelog              # Generate changelog using git-cliff
make docs                   # Open documentation in browser
make docs-md                # Create Markdown API doc with `gomarkdoc` in `docs/API.md`

make clean                  # Clean build artifacts

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Development Setup
  1. Fork the repository
  2. Clone your fork: git clone https://github.com/[yourusername]/zentests.git
  3. Install dependencies: go mod download
  4. Run tests: make test, make test-verbose
  5. Check coverage: make test-coverage
Guidelines
  • Code Quality: Maintain the existing code style and documentation standards
  • Tests: All new features must include comprehensive tests (aim for 100% coverage)
  • Documentation: Update the README.md with any new features or changes
  • Commits: Use clear, descriptive commit messages
  • Compatibility: Ensure changes work with the latest stable Go and Fiber versions
Reporting Issues

Please use GitHub Issues to report bugs or request features. When reporting bugs, include:

  • Go version
  • Fiber version
  • Minimal code example that reproduces the issue
  • Expected vs actual behavior

Credits

Authors:

Inspiration:

  • RSpec - Ruby testing framework that inspired the BDD syntax
  • Pest - PHP testing framework with elegant assertion syntax
  • testify - Go assertion library used internally

Built with:

  • Fiber - Express inspired web framework for Go
  • testify - A toolkit with common assertions

Special thanks to the Go and Fiber communities for their excellent tools and documentation.


License

This code is released under the MIT License.

Copyright (c) 2025 Kematzy

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Documentation

Overview

Package zentests provides utilities for testing Go Fiber applications.

Basic usage:

func TestEndpoint(t *testing.T) {
    zt := zentests.New(t).Use(app)
    zt.Get("/users").ExpectStatus(200)
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SetHeader

func SetHeader(key, value string) map[string]string

SetHeader creates a header map with a single key-value pair. This is a utility function to help construct header maps for custom headers when using raw body request methods.

Parameters:

  • key: The header name
  • value: The header value

Returns:

  • map[string]string: A map containing the single header

Example:

headers := zentests.SetHeader("Authorization", "Bearer token123")
// Use with a method that accepts headers parameter

Types

type Response

type Response struct {
	Header http.Header

	StatusCode int
	// contains filtered or unexported fields
}

Response wraps an HTTP response with fluent assertion methods. It provides a chainable API for making assertions on HTTP responses including status codes, headers, body content, and JSON data. The response body is lazily loaded when first accessed to avoid unnecessary reads.

Response maintains internal state including the parsed JSON body and tracks whether the body has been read to prevent multiple reads from the response stream.

Fields:

  • t: The testing.T instance for making assertions
  • StatusCode: The HTTP status code from the response
  • Header: The HTTP headers from the response
  • resp: The underlying http.Response
  • body: The cached response body bytes (lazy loaded)
  • bodyRead: Flag indicating if body has been read
  • parsedJSON: The parsed JSON body as a map (cached after first parse)

func (*Response) Accepted

func (r *Response) Accepted() *Response

Accepted asserts that the HTTP status code is 202 (Accepted). Convenience method equivalent to Status(202). Indicates the request has been accepted for processing but not completed.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.PostJSON(app, "/jobs", jobData).Accepted()

func (*Response) ArrayLength

func (r *Response) ArrayLength(path string, expected int) *Response

ArrayLength asserts that the JSON key is an array with the expected length.

Parameters:

  • path: The JSON key path using dot notation
  • expected: The expected array length

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users").ArrayLength("data.users", 10)

func (*Response) BadRequest

func (r *Response) BadRequest() *Response

BadRequest asserts that the HTTP status code is 400 (Bad Request). Convenience method equivalent to Status(400). Indicates the server cannot process the request due to client error.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.PostJSON(app, "/users", invalidData).BadRequest()

func (*Response) Body

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

Body returns the response body as bytes. The body is lazily loaded on first call and cached for subsequent accesses. This prevents multiple reads from the response stream which would return empty.

Returns:

  • []byte: The response body as bytes

Example:

body := resp.Body()
fmt.Println(string(body))

func (*Response) BodyMatches

func (r *Response) BodyMatches(pattern string) *Response

BodyMatches asserts that the response body matches the regex pattern. Useful for validating dynamic content or complex text patterns.

Parameters:

  • pattern: The regex pattern to match against the body

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/users/1").BodyMatches(`User ID: \d+`)

func (*Response) BodyString

func (r *Response) BodyString() string

BodyString returns the response body as a string. Convenience method that converts Body() bytes to string.

Returns:

  • string: The response body as a string

Example:

bodyStr := resp.BodyString()
assert.Contains(t, bodyStr, "success")

func (*Response) Contains

func (r *Response) Contains(substring string) *Response

Contains asserts that the response body contains the specified substring. Case-sensitive substring search in the response body.

Parameters:

  • substring: The substring to search for in the body

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/page").Contains("Welcome")

func (*Response) CookieHasValues

func (r *Response) CookieHasValues(expected map[string]string) *Response

CookieHasValues asserts that response cookies match the expected values. Parses all Set-Cookie headers and verifies each cookie name-value pair.

Parameters:

  • expected: Map of cookie names to expected values

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/settings").CookieHasValues(map[string]string{
    "lang": "en",
    "theme": "dark",
})

func (*Response) Created

func (r *Response) Created() *Response

Created asserts that the HTTP status code is 201 (Created). Convenience method equivalent to Status(201). Typically used after POST requests that create new resources.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.PostJSON(app, "/users", data).Created()

func (*Response) Debug

func (r *Response) Debug() *Response

Debug prints detailed response information to stdout for troubleshooting. Outputs status code, headers, body, and parsed JSON (if available). This is useful during test development to inspect response details. Returns the receiver for method chaining.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/users").Debug().OK()

func (*Response) Dump

func (r *Response) Dump() string

Dump returns raw response details as a formatted string. Useful for custom logging or including response details in test failure messages. Unlike Debug(), this returns a string instead of printing to stdout.

Returns:

  • string: Formatted string with status, headers, and body

Example:

details := resp.Dump()
t.Logf("Response details: %s", details)

func (*Response) Equals

func (r *Response) Equals(expected string) *Response

Equals asserts that the response body equals the exact expected string. Performs an exact string comparison of the entire body.

Parameters:

  • expected: The expected body content

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/ping").Equals("pong")

func (*Response) Forbidden

func (r *Response) Forbidden() *Response

Forbidden asserts that the HTTP status code is 403 (Forbidden). Convenience method equivalent to Status(403). Indicates the server understood the request but refuses to authorize it.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/admin").Forbidden()

func (*Response) Has

func (r *Response) Has(path string, expected any) *Response

Has asserts that the JSON key equals the expected value with strict type checking. Supports dot notation for nested keys. Fails if the key doesn't exist or if the type doesn't match exactly.

Parameters:

  • path: The JSON key path using dot notation
  • expected: The expected value (type must match exactly)

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users/1").Has("data.user.name", "John")
zt.Get(app, "/api/count").Has("data.count", float64(42)) // JSON numbers are float64

func (*Response) HasBool

func (r *Response) HasBool(path string, expected bool) *Response

HasBool asserts that the JSON key equals the expected boolean value.

Parameters:

  • path: The JSON key path using dot notation
  • expected: The expected boolean value

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/status").HasBool("data.active", true)

func (*Response) HasContentType

func (r *Response) HasContentType(contentType string) *Response

HasContentType asserts that the Content-Type header equals the expected value. Performs an exact match on the Content-Type header.

Parameters:

  • contentType: The expected Content-Type value (e.g., "application/json")

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/page").HasContentType("text/html; charset=utf-8")

func (*Response) HasFloat

func (r *Response) HasFloat(path string, expected float64) *Response

HasFloat asserts that the JSON key equals the expected float64 value. Uses InDelta for comparison to handle floating point precision issues.

Parameters:

  • path: The JSON key path using dot notation
  • expected: The expected float64 value

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/score").HasFloat("data.score", 95.5)

func (*Response) HasHeader

func (r *Response) HasHeader(key, value string) *Response

HasHeader asserts that a header exists and has the expected value. Performs an exact match comparison. Header names are case-insensitive.

Parameters:

  • key: The header name (e.g., "Content-Type", "X-Custom-Header")
  • value: The expected header value

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users").HasHeader("Content-Type", "application/json")

zt.Get(app, "/api/users").HasHeader("Content-Type", "application/css") // raises an error

func (*Response) HasInt

func (r *Response) HasInt(path string, expected int) *Response

HasInt asserts that the JSON key equals the expected integer value. Handles JSON number conversion (JSON numbers are parsed as float64).

Parameters:

  • path: The JSON key path using dot notation
  • expected: The expected integer value

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/count").HasInt("data.total", 42)

func (*Response) HasKey

func (r *Response) HasKey(path string) *Response

HasKey asserts that the JSON response contains the specified key path. Supports dot notation for nested keys and array indices (e.g., "users.0.name").

Parameters:

  • path: The JSON key path using dot notation (e.g., "user.email", "items.0.id")

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users/1").HasKey("data.user.name")

func (*Response) HasString

func (r *Response) HasString(path, expected string) *Response

HasString asserts that the JSON key equals the expected string value.

Parameters:

  • path: The JSON key path using dot notation
  • expected: The expected string value

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users/1").HasString("data.user.email", "john@example.com")

func (*Response) HeaderContains

func (r *Response) HeaderContains(key, substring string) *Response

HeaderContains asserts that a header value contains the expected substring. Useful for flexible checks like verifying "application/json" is in Content-Type without matching the entire header value including charset.

Parameters:

  • key: The header name
  • substring: The substring that must be present in the header value

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users").HeaderContains("Content-Type", "json")

zt.Get(app, "/api/users").HeaderContains("Content-Type", "image") // raises an error

func (*Response) HeaderHasValues

func (r *Response) HeaderHasValues(key string, values []string) *Response

HeaderHasValues asserts that a header has exactly the expected values. For headers that can have multiple values (e.g., Set-Cookie, X-Features). Order of values does not matter.

Parameters:

  • key: The header name
  • values: Slice of expected header values

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/features").HeaderHasValues("X-Features", []string{"audio", "video"})

func (*Response) HeaderNotPresent

func (r *Response) HeaderNotPresent(key string) *Response

HeaderNotPresent asserts that a header is not present or is empty. Useful for security checks to ensure sensitive headers are not exposed.

Parameters:

  • key: The header name

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/public").HeaderNotPresent("Authorization")

func (*Response) HeaderPresent

func (r *Response) HeaderPresent(key string) *Response

HeaderPresent asserts that a header is present and non-empty. Checks for the existence of a header without validating its value.

Parameters:

  • key: The header name

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/secure").HeaderPresent("X-Auth-Token")

func (*Response) IsCSS

func (r *Response) IsCSS() *Response

IsCSS asserts that the Content-Type header contains "text/css". Quick check for CSS stylesheet responses.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/style.css").OK().IsCSS()

func (*Response) IsEmpty

func (r *Response) IsEmpty() *Response

IsEmpty asserts that the response body is empty. Checks that the body has zero length.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Delete(app, "/users/1").NoContent().IsEmpty()

func (*Response) IsGIF

func (r *Response) IsGIF() *Response

IsGIF asserts that the Content-Type header contains "image/gif". Quick check for GIF image responses.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/animation.gif").OK().IsGIF()

func (*Response) IsHTML

func (r *Response) IsHTML() *Response

IsHTML asserts that the Content-Type header contains "text/html". Quick check for HTML page responses. Case-sensitive substring match.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/").OK().IsHTML()

func (*Response) IsImage

func (r *Response) IsImage() *Response

IsImage asserts that the Content-Type header contains "image/". General check for any image type responses.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/photo.jpg").OK().IsImage()

func (*Response) IsJPEG

func (r *Response) IsJPEG() *Response

IsJPEG asserts that the Content-Type header contains "image/jpeg". Quick check for JPEG image responses.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/photo.jpg").OK().IsJPEG()

func (*Response) IsJS

func (r *Response) IsJS() *Response

IsJS asserts that the Content-Type header contains "javascript". Matches both "application/javascript" and "text/javascript". Quick check for JavaScript responses.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/app.js").OK().IsJS()

func (*Response) IsJSON

func (r *Response) IsJSON() *Response

IsJSON asserts that the Content-Type header contains "application/json". Quick check for JSON API responses. Case-sensitive substring match.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users").OK().IsJSON()

func (*Response) IsNotNull

func (r *Response) IsNotNull(path string) *Response

IsNotNull asserts that the JSON key has a non-null value.

Parameters:

  • path: The JSON key path using dot notation

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users/1").IsNotNull("data.user")

func (*Response) IsNull

func (r *Response) IsNull(path string) *Response

IsNull asserts that the JSON key has a null value.

Parameters:

  • path: The JSON key path using dot notation

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users/999").IsNull("data.user")

func (*Response) IsPNG

func (r *Response) IsPNG() *Response

IsPNG asserts that the Content-Type header contains "image/png". Quick check for PNG image responses.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/logo.png").OK().IsPNG()

func (*Response) IsPlainText

func (r *Response) IsPlainText() *Response

IsPlainText asserts that the Content-Type header contains "text/plain". Quick check for plain text responses. Case-sensitive substring match.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/health").OK().IsPlainText()

func (*Response) IsSVG

func (r *Response) IsSVG() *Response

IsSVG asserts that the Content-Type header contains "image/svg+xml". Quick check for SVG image responses.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/icon.svg").OK().IsSVG()

func (*Response) IsWebP

func (r *Response) IsWebP() *Response

IsWebP asserts that the Content-Type header contains "image/webp". Quick check for WebP image responses.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/photo.webp").OK().IsWebP()

func (*Response) IsXHR

func (r *Response) IsXHR() *Response

IsXHR asserts that the X-Requested-With header contains "XMLHttpRequest". Useful for detecting AJAX requests in responses.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users").OK().IsXHR()

func (*Response) IsXML

func (r *Response) IsXML() *Response

IsXML asserts that the Content-Type header contains "xml". Matches both "application/xml" and "text/xml". Quick check for XML responses.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/data.xml").OK().IsXML()

func (*Response) JSON

func (r *Response) JSON() *Response

JSON parses and caches the response body as JSON. Enables JSON-specific assertions on the response. The parsed JSON is cached to avoid re-parsing on subsequent JSON assertions. Fails the test if JSON parsing fails.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users").JSON().Has("data.0.name", "John")

func (*Response) JSONMatches

func (r *Response) JSONMatches(expected map[string]any) *Response

JSONMatches asserts that the entire JSON structure matches the expected map. Performs Has() assertions for each key-value pair in the expected map.

Parameters:

  • expected: Map of key paths to expected values

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users/1").JSONMatches(map[string]interface{}{
    "data.user.name": "John",
    "data.user.active": true,
})

func (*Response) MatchesRegex

func (r *Response) MatchesRegex(path, pattern string) *Response

MatchesRegex asserts that the JSON key value matches the regex pattern. The value at the specified path must be a string.

Parameters:

  • path: The JSON key path using dot notation
  • pattern: The regex pattern to match

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/api/users/1").MatchesRegex("data.user.email", `^[\w.-]+@[\w.-]+\.\w+$`)

func (*Response) NoContent

func (r *Response) NoContent() *Response

NoContent asserts that the HTTP status code is 204 (No Content). Convenience method equivalent to Status(204). Typically used for DELETE operations or successful operations with no response body.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Delete(app, "/users/1").NoContent()

func (*Response) NotContains

func (r *Response) NotContains(substring string) *Response

NotContains asserts that the response body does not contain the specified substring. Useful for ensuring sensitive data is not present in responses.

Parameters:

  • substring: The substring that should not be in the body

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/public").NotContains("password")

func (*Response) NotFound

func (r *Response) NotFound() *Response

NotFound asserts that the HTTP status code is 404 (Not Found). Convenience method equivalent to Status(404). Indicates the requested resource was not found.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/users/999").NotFound()

func (*Response) OK

func (r *Response) OK() *Response

OK asserts that the HTTP status code is 200 (OK). Convenience method equivalent to Status(200).

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/users").OK()

func (*Response) ServerError

func (r *Response) ServerError() *Response

ServerError asserts that the HTTP status code is 500 (Internal Server Error). Convenience method equivalent to Status(500). Indicates an unexpected condition prevented the server from fulfilling the request.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/broken").ServerError()

func (*Response) Status

func (r *Response) Status(expected int) *Response

Status asserts that the HTTP status code equals the expected value. This is the base status assertion method used by all other status shortcuts.

Parameters:

  • expected: The expected HTTP status code (e.g., 200, 404, 500)

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/users").Status(200)
zt.Get(app, "/notfound").Status(404)

func (*Response) Unauthorized

func (r *Response) Unauthorized() *Response

Unauthorized asserts that the HTTP status code is 401 (Unauthorized). Convenience method equivalent to Status(401). Indicates authentication is required or has failed.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.Get(app, "/protected").Unauthorized()

func (*Response) Unprocessable

func (r *Response) Unprocessable() *Response

Unprocessable asserts that the HTTP status code is 422 (Unprocessable Entity). Convenience method equivalent to Status(422). Indicates the request was well-formed but contains semantic errors.

Returns:

  • *Response: The receiver for method chaining

Example:

zt.PostJSON(app, "/users", invalidUserData).Unprocessable()

type SuiteContext

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

SuiteContext holds hooks and state for a BDD-style describe block. Provides lifecycle hooks (BeforeEach, AfterEach) for test setup and teardown. Each describe block gets its own SuiteContext to manage test isolation.

Fields:

  • t: The testing.T instance for running subtests
  • beforeEach: Function to run before each test case in the suite
  • afterEach: Function to run after each test case in the suite

func (*SuiteContext) AfterEach

func (ctx *SuiteContext) AfterEach(fn func(*T)) *SuiteContext

AfterEach sets the teardown hook function to run after each test case. Use this for cleanup like closing database connections or shutting down apps. Returns the SuiteContext for method chaining.

Parameters:

  • fn: Function to execute after each test case, receives *T

Returns:

  • *SuiteContext: The receiver for method chaining

Example:

ctx.AfterEach(func(zt *zentests.T) {
    app.Shutdown()
    db.Cleanup()
})

func (*SuiteContext) BeforeEach

func (ctx *SuiteContext) BeforeEach(fn func(*T)) *SuiteContext

BeforeEach sets the setup hook function to run before each test case. Use this for common setup like creating fresh app instances or test data. Returns the SuiteContext for method chaining with AfterEach.

Parameters:

  • fn: Function to execute before each test case, receives *T

Returns:

  • *SuiteContext: The receiver for method chaining

Example:

ctx.BeforeEach(func(zt *zentests.T) {
    app = fiber.New()
    SetupRoutes(app)
}).AfterEach(func(zt *zentests.T) {
    app.Shutdown()
})

func (*SuiteContext) It

func (ctx *SuiteContext) It(name string, fn func(*T))

It runs a test case within a describe block. Individual test cases that execute with BeforeEach/AfterEach hooks. Each It() call creates a sub-test that runs independently.

Parameters:

  • name: The descriptive name for the test case (e.g., "returns user list")
  • fn: The test function receiving a *T for making requests

Example:

ctx.It("returns user list", func(zt *zentests.T) {
    zt.Get(app, "/users").OK().IsJSON()
})

type T

type T struct {
	*testing.T
	// contains filtered or unexported fields
}

T wraps testing.T with additional context for testing Fiber applications. It provides a fluent API for making HTTP requests against a Fiber app in tests. T maintains a reference to the Fiber app and testing context to enable chainable assertions.

Basic usage:

func TestEndpoint(t *testing.T) {
    zt := zentests.New(t).Use(app)
    zt.Get("/users").ExpectStatus(200)
}

Fields:

  • T: The embedded testing.T instance for standard Go test functionality
  • app: The Fiber application instance for making HTTP requests

func New

func New(t *testing.T) *T

New creates a new zentests context wrapping the provided testing.T. This is the main entry point for using zentests. The returned *T has no app set initially - call Use() to set the Fiber application for method chaining, or pass the app directly to request methods like Get(app, "/").

Parameters:

  • t: The testing.T instance from your test function

Returns:

  • *T: A new zentests context with no Fiber app configured

Example:

func TestExample(t *testing.T) {
	zt := zentests.New(t)
	app := fiber.New()
	// declare app routes
	zt.Use(app)
}

func TestExample(t *testing.T) {
    zt := zentests.New(t)
    app := fiber.New()
    // declare app routes

    zt.Get(app, "/").OK()
}

func (*T) Delete

func (zt *T) Delete(app *fiber.App, path string) *Response

Delete performs a DELETE request. Returns a *Response for chaining assertions. Use this for testing DELETE endpoints.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/1")

Returns:

  • *Response: A Response wrapper for making assertions

Example:

zt.Delete(app, "/users/1").NoContent()

func (*T) DeleteJSON

func (zt *T) DeleteJSON(app *fiber.App, path string, data any) *Response

DeleteJSON performs a DELETE request with a JSON body. Some APIs require a request body for DELETE operations (e.g., bulk delete with IDs). Automatically marshals the data to JSON and sets Content-Type to application/json.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/bulk")
  • data: Any data structure to be JSON-encoded

Returns:

  • *Response: A Response wrapper for making assertions

Example:

data := map[string][]int{"ids": {1, 2, 3}}
zt.DeleteJSON(app, "/users/bulk", data).OK()

func (*T) DeleteJSONWithConfig added in v0.2.0

func (zt *T) DeleteJSONWithConfig(app *fiber.App, path string, data any, cfg fiber.TestConfig) *Response

DeleteJSONWithConfig performs a DELETE request with JSON body and custom TestConfig.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/bulk")
  • data: Any data structure to be JSON-encoded
  • cfg: TestConfig for custom timeout/behavior settings

Returns:

  • *Response: A Response wrapper for making assertions

func (*T) DeleteWithConfig added in v0.2.0

func (zt *T) DeleteWithConfig(app *fiber.App, path string, cfg fiber.TestConfig) *Response

DeleteWithConfig performs a DELETE request with custom TestConfig.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/1")
  • cfg: TestConfig for custom timeout/behavior settings

Returns:

  • *Response: A Response wrapper for making assertions

func (*T) Describe

func (zt *T) Describe(name string, fn func(ctx *SuiteContext))

Describe creates a BDD-style test group with lifecycle hooks. Organizes related tests under a descriptive name with optional setup/teardown. Similar to describe/it blocks in testing frameworks like RSpec or Mocha.

Parameters:

  • name: The descriptive name for the test group (e.g., "User API", "Auth Service")
  • fn: Function that receives the SuiteContext and defines test cases using It()

Example:

zt.Describe("User API", func(ctx *zentests.SuiteContext) {
    ctx.BeforeEach(func(zt *zentests.T) {
        // Setup fresh app before each test
        app = setupTestApp()
    })

    ctx.It("creates a user", func(zt *zentests.T) {
        zt.PostJSON(app, "/users", data).Created()
    })
})

func (*T) Get

func (zt *T) Get(app *fiber.App, path string) *Response

Get performs a GET request against the Fiber app. Returns a *Response for chaining assertions. Use this for testing GET endpoints.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users")

Returns:

  • *Response: A Response wrapper for making assertions

Example:

zt := zentests.New(t)
resp := zt.Get(app, "/users")
resp.OK().IsJSON().Has("data.users.0.name", "John")

func (*T) GetWithConfig added in v0.2.0

func (zt *T) GetWithConfig(app *fiber.App, path string, cfg fiber.TestConfig) *Response

GetWithConfig performs a GET request with custom TestConfig for timeout/behavior control. Use this when you need to customize test behavior beyond defaults.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users")
  • cfg: TestConfig for custom timeout/behavior settings

Returns:

  • *Response: A Response wrapper for making assertions

Example:

zt.GetWithConfig(app, "/slow-endpoint", fiber.TestConfig{
    Timeout: 5 * time.Second,
}).OK()

func (*T) Patch

func (zt *T) Patch(app *fiber.App, path string, body []byte) *Response

Patch performs a PATCH request with a raw body. Use PatchJSON for JSON payloads. PATCH is typically used for partial resource updates.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/1")
  • body: The raw request body as bytes

Returns:

  • *Response: A Response wrapper for making assertions

Example:

body := []byte(`{"status": "active"}`)
zt.Patch(app, "/users/1", body).OK()

func (*T) PatchJSON

func (zt *T) PatchJSON(app *fiber.App, path string, data any) *Response

PatchJSON performs a PATCH request with JSON-encoded data. Automatically marshals the data to JSON and sets Content-Type to application/json. Fails the test if JSON marshaling fails. PATCH is typically used for partial updates.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/1")
  • data: Any data structure to be JSON-encoded

Returns:

  • *Response: A Response wrapper for making assertions

Example:

data := map[string]string{"status": "active"}
zt.PatchJSON(app, "/users/1", data).OK()

func (*T) PatchJSONWithConfig added in v0.2.0

func (zt *T) PatchJSONWithConfig(app *fiber.App, path string, data any, cfg fiber.TestConfig) *Response

PatchJSONWithConfig performs a PATCH request with JSON data and custom TestConfig.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/1")
  • data: Any data structure to be JSON-encoded
  • cfg: TestConfig for custom timeout/behavior settings

Returns:

  • *Response: A Response wrapper for making assertions

func (*T) PatchWithConfig added in v0.2.0

func (zt *T) PatchWithConfig(app *fiber.App, path string, body []byte, cfg fiber.TestConfig) *Response

PatchWithConfig performs a PATCH request with raw body and custom TestConfig.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/1")
  • body: The raw request body as bytes
  • cfg: TestConfig for custom timeout/behavior settings

Returns:

  • *Response: A Response wrapper for making assertions

func (*T) Post

func (zt *T) Post(app *fiber.App, path string, body []byte) *Response

Post performs a POST request with a raw body. Use PostJSON for JSON payloads or PostForm for form data. This method is suitable for sending raw bytes when you need full control over the request body.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users")
  • body: The raw request body as bytes

Returns:

  • *Response: A Response wrapper for making assertions

Example:

body := []byte("raw data")
zt.Post(app, "/upload", body).OK()

func (*T) PostForm

func (zt *T) PostForm(app *fiber.App, path string, data map[string]string) *Response

PostForm performs a POST request with form data. Automatically encodes the data as application/x-www-form-urlencoded. Useful for testing HTML form submissions or traditional form endpoints.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/login")
  • data: Map of form field names to values

Returns:

  • *Response: A Response wrapper for making assertions

Example:

data := map[string]string{"username": "john", "password": "secret"}
zt.PostForm(app, "/login", data).OK()

func (*T) PostFormWithConfig added in v0.2.0

func (zt *T) PostFormWithConfig(app *fiber.App, path string, data map[string]string, cfg fiber.TestConfig) *Response

PostFormWithConfig performs a POST request with form data and custom TestConfig.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/login")
  • data: Map of form field names to values
  • cfg: TestConfig for custom timeout/behavior settings

Returns:

  • *Response: A Response wrapper for making assertions

Example:

zt.PostFormWithConfig(app, "/login", data, fiber.TestConfig{
    Timeout: 5 * time.Second,
}).OK()

func (*T) PostJSON

func (zt *T) PostJSON(app *fiber.App, path string, data any) *Response

PostJSON performs a POST request with JSON-encoded data. Automatically marshals the data to JSON and sets Content-Type to application/json. Fails the test if JSON marshaling fails.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users")
  • data: Any data structure to be JSON-encoded (maps, structs, etc.)

Returns:

  • *Response: A Response wrapper for making assertions

Example:

data := map[string]string{"name": "John", "email": "john@example.com"}
zt.PostJSON(app, "/users", data).Created().Has("id", float64(1))

func (*T) PostJSONWithConfig added in v0.2.0

func (zt *T) PostJSONWithConfig(app *fiber.App, path string, data any, cfg fiber.TestConfig) *Response

PostJSONWithConfig performs a POST request with JSON data and custom TestConfig.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users")
  • data: Any data structure to be JSON-encoded
  • cfg: TestConfig for custom timeout/behavior settings

Returns:

  • *Response: A Response wrapper for making assertions

Example:

zt.PostJSONWithConfig(app, "/users", data, fiber.TestConfig{
    Timeout:       5 * time.Second,
    FailOnTimeout: true,
}).Created()

func (*T) PostWithConfig added in v0.2.0

func (zt *T) PostWithConfig(app *fiber.App, path string, body []byte, cfg fiber.TestConfig) *Response

PostWithConfig performs a POST request with raw body and custom TestConfig.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users")
  • body: The raw request body as bytes
  • cfg: TestConfig for custom timeout/behavior settings

Returns:

  • *Response: A Response wrapper for making assertions

Example:

zt.PostWithConfig(app, "/upload", body, fiber.TestConfig{
    Timeout: 10 * time.Second,
}).OK()

func (*T) Put

func (zt *T) Put(app *fiber.App, path string, body []byte) *Response

Put performs a PUT request with a raw body. Use PutJSON for JSON payloads. PUT is typically used for full resource updates.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/1")
  • body: The raw request body as bytes

Returns:

  • *Response: A Response wrapper for making assertions

Example:

body := []byte(`{"name": "Updated Name"}`)
zt.Put(app, "/users/1", body).OK()

func (*T) PutJSON

func (zt *T) PutJSON(app *fiber.App, path string, data any) *Response

PutJSON performs a PUT request with JSON-encoded data. Automatically marshals the data to JSON and sets Content-Type to application/json. Fails the test if JSON marshaling fails. PUT is typically used for full resource updates.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/1")
  • data: Any data structure to be JSON-encoded

Returns:

  • *Response: A Response wrapper for making assertions

Example:

data := map[string]string{"name": "Updated Name"}
zt.PutJSON(app, "/users/1", data).OK()

func (*T) PutJSONWithConfig added in v0.2.0

func (zt *T) PutJSONWithConfig(app *fiber.App, path string, data any, cfg fiber.TestConfig) *Response

PutJSONWithConfig performs a PUT request with JSON data and custom TestConfig.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/1")
  • data: Any data structure to be JSON-encoded
  • cfg: TestConfig for custom timeout/behavior settings

Returns:

  • *Response: A Response wrapper for making assertions

func (*T) PutWithConfig added in v0.2.0

func (zt *T) PutWithConfig(app *fiber.App, path string, body []byte, cfg fiber.TestConfig) *Response

PutWithConfig performs a PUT request with raw body and custom TestConfig.

Parameters:

  • app: The Fiber application to test against
  • path: The request path (e.g., "/api/users/1")
  • body: The raw request body as bytes
  • cfg: TestConfig for custom timeout/behavior settings

Returns:

  • *Response: A Response wrapper for making assertions

func (*T) Use

func (zt *T) Use(app *fiber.App) *T

Use sets the Fiber app for making test requests and enables fluent method chaining. After calling Use(), subsequent request methods can be called without passing the app parameter.

Parameters:

  • app: The Fiber application instance to test against

Returns:

  • *T: The receiver for method chaining

TODO: Add nil check for app parameter to prevent panics

Example:

zt := zentests.New(t).Use(app)
zt.Get("/users").OK()

Jump to

Keyboard shortcuts

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