httpstub

package module
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2024 License: MIT Imports: 29 Imported by: 3

README

httpstub Go Reference Coverage Code to Test Ratio Test Execution Time

httpstub provides router ( http.Handler ), server ( *httptest.Server ) and client ( *http.Client ) for stubbing, for testing in Go.

There is an gRPC version stubbing tool with the same design concept, grpcstub.

Usage

package myapp

import (
	"io"
	"net/http"
	"testing"

	"github.com/k1LoW/httpstub"
)

func TestGet(t *testing.T) {
	ts := httpstub.NewServer(t)
	t.Cleanup(func() {
		ts.Close()
	})
	ts.Method(http.MethodGet).Path("/api/v1/users/1").Header("Content-Type", "application/json").ResponseString(http.StatusOK, `{"name":"alice"}`)

	res, err := http.Get(ts.URL + "/api/v1/users/1")
	if err != nil {
		t.Fatal(err)
	}
	t.Cleanup(func() {
		res.Body.Close()
	})
	body, err := io.ReadAll(res.Body)
	if err != nil {
		t.Fatal(err)
	}
	got := string(body)
	want := `{"name":"alice"}`
	if got != want {
		t.Errorf("got %v\nwant %v", got, want)
	}
	if len(ts.Requests()) != 1 {
		t.Errorf("got %v\nwant %v", len(ts.Requests()), 1)
	}
}

or

package myapp

import (
	"io"
	"net/http"
	"testing"

	"github.com/k1LoW/httpstub"
)

func TestGet(t *testing.T) {
	r := httpstub.NewRouter(t)
	r.Method(http.MethodGet).Path("/api/v1/users/1").Header("Content-Type", "application/json").ResponseString(http.StatusOK, `{"name":"alice"}`)
	ts := r.Server()
	t.Cleanup(func() {
		ts.Close()
	})

	res, err := http.Get(ts.URL + "/api/v1/users/1")
	if err != nil {
		t.Fatal(err)
	}
	t.Cleanup(func() {
		res.Body.Close()
	})
	body, err := io.ReadAll(res.Body)
	if err != nil {
		t.Fatal(err)
	}
	got := string(body)
	want := `{"name":"alice"}`
	if got != want {
		t.Errorf("got %v\nwant %v", got, want)
	}
	if len(r.Requests()) != 1 {
		t.Errorf("got %v\nwant %v", len(r.Requests()), 1)
	}
}

Response using examples: of OpenAPI Document

httpstub can return responses using examples: of OpenAPI Document.

Use examples: in all responses
ts := httpstub.NewServer(t, httpstub.OpenApi3("path/to/schema.yml"))
t.Cleanup(func() {
	ts.Close()
})
ts.ResponseExample()
Use examples: in response to specific endpoint
ts := httpstub.NewServer(t, httpstub.OpenApi3("path/to/schema.yml"))
t.Cleanup(func() {
	ts.Close()
})
ts.Method(http.MethodGet).Path("/api/v1/users/1").ResponseExample()
Use specific status code examples: in the response

It is possible to specify status codes using wildcard.

ts := httpstub.NewServer(t, httpstub.OpenApi3("path/to/schema.yml"))
t.Cleanup(func() {
	ts.Close()
})
ts.Method(http.MethodPost).Path("/api/v1/users").ResponseExample(httpstub.Status("2*"))
HTTP Client that always makes HTTP request to stub server

It is possible to create a client that will always make an HTTP request to the stub server.

ts := httpstub.NewServer(t)
t.Cleanup(func() {
	ts.Close()
})
ts.Method(http.MethodGet).Path("/api/v1/users/1").Header("Content-Type", "application/json").ResponseString(http.StatusOK, `{"name":"alice"}`)
tc := ts.Client()

res, err := tc.Get("https://example.com/api/v1/users/1") // Request goes to stub server instead of https://example.com
if err != nil {
	t.Fatal(err)
}

Example

Stub Twilio
package client_test

import (
	"net/http"
	"testing"

	"github.com/k1LoW/httpstub"
	twilio "github.com/twilio/twilio-go"
	twclient "github.com/twilio/twilio-go/client"
	api "github.com/twilio/twilio-go/rest/api/v2010"
)

func TestTwilioClient(t *testing.T) {
	r := httpstub.NewRouter(t)
	r.Method(http.MethodPost).Path("/2010-04-01/Accounts/*/Messages.json").ResponseString(http.StatusCreated, `{"status":"sending"}`)
	ts := r.Server()
	t.Cleanup(func() {
		ts.Close()
	})
	tc := ts.Client()

	accountSid := "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
	authToken := "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
	client := twilio.NewRestClientWithParams(twilio.ClientParams{
		Client: &twclient.Client{
			Credentials: twclient.NewCredentials(accountSid, authToken),
			HTTPClient:  tc,
		},
	})
	params := &api.CreateMessageParams{}
	params.SetTo("08000000000")
	params.SetFrom("05000000000")
	params.SetBody("Hello there")
	res, err := client.ApiV2010.CreateMessage(params)
	if err != nil {
		t.Error(err)
	}

	got := res.Status
	want := "sending"
	if *got != want {
		t.Errorf("got %v\nwant %v", *got, want)
	}
}

Alternatives

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Status added in v0.9.0

func Status(pattern string) responseExampleOption

Status specify the example response to use by status code

Types

type Option added in v0.4.0

type Option func(*config) error

func CACert added in v0.4.1

func CACert(cacert []byte) Option

CACert set CA

func Certificates added in v0.4.1

func Certificates(cert, key []byte) Option

Certificates set certificates ( cert, key )

func ClientCACert added in v0.5.0

func ClientCACert(cacert []byte) Option

ClientCACert set client CA

func ClientCertificates added in v0.5.0

func ClientCertificates(cert, key []byte) Option

ClientCertificates set client certificates ( cert, key )

func OpenApi3 added in v0.8.0

func OpenApi3(l string) Option

OpenApi3 sets OpenAPI Document using file path.

func OpenApi3FromData added in v0.8.0

func OpenApi3FromData(b []byte) Option

OpenApi3FromData sets OpenAPI Document from bytes

func SkipValidateRequest added in v0.8.0

func SkipValidateRequest(skip bool) Option

SkipValidateRequest sets whether to skip validation of HTTP request with OpenAPI Document.

func SkipValidateResponse added in v0.8.0

func SkipValidateResponse(skip bool) Option

SkipValidateResponse sets whether to skip validation of HTTP response with OpenAPI Document.

func UseTLS added in v0.4.0

func UseTLS() Option

UseTLS enable TLS

func UseTLSWithCertificates added in v0.4.0

func UseTLSWithCertificates(cert, key []byte) Option

UseTLSWithCertificates enable TLS with certificates ( cert, key )

type Router added in v0.3.0

type Router struct {
	// Set *httptest.Server.URL
	URL string
	// contains filtered or unexported fields
}

func NewRouter

func NewRouter(t TB, opts ...Option) *Router

NewRouter returns a new router with methods for stubbing.

func NewServer added in v0.2.0

func NewServer(t TB, opts ...Option) *Router

NewServer returns a new router including *httptest.Server.

func NewTLSServer added in v0.4.0

func NewTLSServer(t TB, opts ...Option) *Router

NewTLSServer returns a new router including TLS *httptest.Server.

func (*Router) ClearRequests added in v0.6.0

func (rt *Router) ClearRequests()

ClearRequests clear []*http.Request received by router.

func (*Router) Client added in v0.3.0

func (rt *Router) Client() *http.Client

Client returns *http.Client which requests *httptest.Server.

func (*Router) Close added in v0.3.0

func (rt *Router) Close()

Close shuts down *httptest.Server

func (*Router) DefaultHeader added in v0.3.0

func (rt *Router) DefaultHeader(key, value string)

DefaultHeader append default middleware which append header.

func (*Router) DefaultMiddleware added in v0.3.0

func (rt *Router) DefaultMiddleware(mw func(next http.HandlerFunc) http.HandlerFunc)

DefaultMiddleware append default middleware.

func (*Router) Match added in v0.3.0

func (rt *Router) Match(fn func(r *http.Request) bool) *matcher

Match create request matcher with matchFunc (func(r *http.Request) bool).

func (*Router) Method added in v0.3.0

func (rt *Router) Method(method string) *matcher

Method create request matcher using method.

func (*Router) Path added in v0.3.0

func (rt *Router) Path(path string) *matcher

Path create request matcher using path.

func (*Router) Pathf added in v0.7.0

func (rt *Router) Pathf(format string, a ...any) *matcher

Pathf create request matcher using sprintf-ed path.

func (*Router) Query added in v0.9.0

func (rt *Router) Query(key, value string) *matcher

Query create request matcher using query.

func (*Router) Requests added in v0.3.0

func (rt *Router) Requests() []*http.Request

Requests returns []*http.Request received by router.

func (*Router) ResponseExample added in v0.9.0

func (rt *Router) ResponseExample(opts ...responseExampleOption)

ResponseExample set handler which return response using examples of OpenAPI v3 Document

func (*Router) ServeHTTP added in v0.3.0

func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*Router) Server added in v0.3.0

func (rt *Router) Server() *httptest.Server

Server returns *httptest.Server with *Router set.

func (*Router) TLSServer added in v0.4.0

func (rt *Router) TLSServer() *httptest.Server

TLSServer returns TLS *httptest.Server with *Router set.

type TB added in v0.8.0

type TB interface {
	Error(args ...any)
	Errorf(format string, args ...any)
	Fatal(args ...any)
	Fatalf(format string, args ...any)
	Helper()
}

Directories

Path Synopsis
Package mock_httpstub is a generated GoMock package.
Package mock_httpstub is a generated GoMock package.

Jump to

Keyboard shortcuts

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