contest

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Feb 10, 2026 License: MIT Imports: 11 Imported by: 0

README

contest

contest is a lightweight DSL for testing ConnectRPC handlers. It executes handlers directly using Go's httptest package, automatically decodes connect.Error responses, and provides a fluent, expressive API for asserting response behavior.


Features

  • Runs Connect handlers directly without a network layer
  • Automatically unmarshals connect.Error JSON responses
  • Provides fluent assertion methods:
    • ExpectStatus
    • ExpectHeader
    • Out (for unmarshalling protobuf responses)
    • Err (returns *connect.Error if present)
  • Supports structured error detail decoding (connect.ErrorDetail)
  • Compatible with connect.WithInterceptors(...)

Example

package handler_test

import (
	"net/http"
	"testing"

	"connectrpc.com/connect"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/mickamy/contest"
	authv1 "github.com/mickamy/contest/example/gen/auth/v1"
	"github.com/mickamy/contest/example/gen/github.com/mickamy/contest/example/gen/auth/v1/authv1connect"
	"github.com/mickamy/contest/example/internal/domain/session/handler"
)

func TestSession_SignIn(t *testing.T) {
	t.Parallel()

	var out authv1.SignInResponse

	_, server := authv1connect.NewSessionServiceHandler(handler.NewSession())
	ct := contest.
		New(t, server).
		Procedure(authv1connect.SessionServiceSignInProcedure).
		In(&authv1.SignInRequest{
			Email:    "user@example.com",
			Password: "password123",
		}).
		Do().
		ExpectStatus(http.StatusOK)

	ct.Out(&out)
	require.NotZero(t, out.Tokens)
	assert.NotZero(t, out.Tokens.Access)
	assert.NotZero(t, out.Tokens.Refresh)
}

API Overview

Creating a client
ct := contest.New(t, handler)
Configuring a request
ct.Procedure("/package.Service/Method").Header("X-Test", "1").In(&req)
Executing and asserting
ct.Do().ExpectStatus(http.StatusOK).Out(&res)
Handling errors
if connErr := ct.Err(); connErr != nil {
    fmt.Println(connErr.Code(), connErr.Message())
}

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Bind added in v0.0.3

func Bind[H any](newHandler func(H, ...connect.HandlerOption) (string, http.Handler)) func(H) NewHandlerFunc

Types

type Client

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

func New

func New(t T, h http.Handler) *Client

func NewWith added in v0.0.3

func NewWith(t T, f NewHandlerFunc, opts ...connect.HandlerOption) *Client

func (*Client) Do

func (c *Client) Do() *Client

func (*Client) Err

func (c *Client) Err() *connect.Error

func (*Client) ExpectHeader

func (c *Client) ExpectHeader(key string, want ...string) *Client

func (*Client) ExpectStatus

func (c *Client) ExpectStatus(code int) *Client

func (*Client) Header

func (c *Client) Header(key, value string) *Client

func (*Client) In

func (c *Client) In(msg proto.Message) *Client

func (*Client) Out

func (c *Client) Out(dst proto.Message) *Client

func (*Client) Procedure

func (c *Client) Procedure(proc string) *Client

type NewHandlerFunc added in v0.0.3

type NewHandlerFunc = func(...connect.HandlerOption) (string, http.Handler)

type T

type T interface {
	Helper()
	Fatalf(format string, args ...any)
	Logf(format string, args ...any)
}

Jump to

Keyboard shortcuts

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