httptest

package
v0.55.0 Latest Latest
Warning

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

Go to latest
Published: May 4, 2024 License: BSD-3-Clause Imports: 8 Imported by: 0

Documentation

Overview

Package httptest implement testing HTTP package.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type SimulateRequest

type SimulateRequest struct {
	Method string
	Path   string

	// JSONIndentResponse if not empty, the response body will be
	// indented using [json.Indent].
	JSONIndentResponse string

	Header http.Header
	Body   []byte
}

SimulateRequest request to simulate http.ServeHTTP.

type SimulateResult

type SimulateResult struct {
	Request  *http.Request  `json:"-"`
	Response *http.Response `json:"-"`

	RequestDump  []byte
	ResponseDump []byte
	ResponseBody []byte
}

SimulateResult contains http.Request and http.Response from calling http.ServeHTTP.

func Simulate

func Simulate(serve http.HandlerFunc, req *SimulateRequest) (result *SimulateResult, err error)

Simulate HTTP server handler by generating http.Request from fields in SimulateRequest; and then call http.HandlerFunc. The HTTP response from serve along with its raw body and original HTTP request then returned in *SimulateResult.

Example
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"

	"git.sr.ht/~shulhan/pakakeh.go/lib/test/httptest"
)

func main() {
	http.HandleFunc(`/a/b/c`, func(w http.ResponseWriter, req *http.Request) {
		_ = req.ParseForm()
		var (
			rawjson []byte
			err     error
		)
		rawjson, err = json.Marshal(req.PostForm)
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.Header().Set(`Content-Type`, `application/json`)
		_, _ = w.Write(rawjson)
	})

	var simreq = &httptest.SimulateRequest{
		Method: http.MethodPost,
		Path:   `/a/b/c`,
		Header: http.Header{
			`Content-Type`: []string{`application/x-www-form-urlencoded`},
		},
		Body:               []byte(`id=1&name=go`),
		JSONIndentResponse: `  `,
	}

	var (
		result *httptest.SimulateResult
		err    error
	)

	result, err = httptest.Simulate(http.DefaultServeMux.ServeHTTP, simreq)
	if err != nil {
		log.Fatal(err)
	}

	var dump []byte

	dump, err = result.DumpRequest(nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("<<< RequestDump:\n%s\n\n", dump)

	dump, err = result.DumpResponse(nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("<<< ResponseDump:\n%s\n\n", dump)
	fmt.Printf("<<< ResponseBody:\n%s\n", result.ResponseBody)

}
Output:

<<< RequestDump:
POST /a/b/c HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

id=1&name=go

<<< ResponseDump:
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json

{
  "id": [
    "1"
  ],
  "name": [
    "go"
  ]
}

<<< ResponseBody:
{
  "id": [
    "1"
  ],
  "name": [
    "go"
  ]
}

func (*SimulateResult) DumpRequest

func (result *SimulateResult) DumpRequest(excludeHeaders []string) (raw []byte, err error)

DumpRequest convert [SimulateResult.Request] with its body to stream of bytes using httputil.DumpRequest.

The returned bytes have CRLF ("\r\n") replaced with single LF ("\n").

Any request headers that match with excludeHeaders will be deleted before dumping.

Example
package main

import (
	"fmt"
	"log"
	"net/http"

	libhttptest "git.sr.ht/~shulhan/pakakeh.go/lib/test/httptest"
)

func main() {
	var (
		req *http.Request
		err error
	)

	req, err = http.NewRequest(http.MethodGet, `/a/b/c`, nil)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set(`h1`, `v1`)
	req.Header.Set(`h2`, `v2`)
	req.Header.Set(`h3`, `v3`)

	var sim = libhttptest.SimulateResult{
		Request: req,
	}

	var got []byte

	got, err = sim.DumpRequest([]string{`h1`})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("DumpRequest:\n%s", got)

	sim.RequestDump = nil

	got, err = sim.DumpRequest([]string{`h3`})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("DumpRequest:\n%s", got)

}
Output:

DumpRequest:
GET /a/b/c HTTP/1.1
H2: v2
H3: v3

DumpRequest:
GET /a/b/c HTTP/1.1
H1: v1
H2: v2

func (*SimulateResult) DumpResponse

func (result *SimulateResult) DumpResponse(excludeHeaders []string) (raw []byte, err error)

DumpResponse convert [SimulateResult.Response] with its body to stream of bytes using httputil.DumpResponse.

The returned bytes have CRLF ("\r\n") replaced with single LF ("\n").

Any response headers that match with excludeHeaders will be deleted before dumping.

Example
package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/httptest"

	libhttptest "git.sr.ht/~shulhan/pakakeh.go/lib/test/httptest"
)

func main() {
	var handler = func(w http.ResponseWriter, _ *http.Request) {
		w.Header().Set(`h1`, `v1`)
		w.Header().Set(`h2`, `v2`)
		w.Header().Set(`h3`, `v3`)
		_, _ = io.WriteString(w, `Hello world!`)
	}

	var (
		ctx = context.Background()

		req *http.Request
		err error
	)

	req, err = http.NewRequestWithContext(ctx, http.MethodGet, `/a/b/c`, nil)
	if err != nil {
		log.Fatal(err)
	}

	var recorder = httptest.NewRecorder()

	handler(recorder, req)

	var result = libhttptest.SimulateResult{
		Response: recorder.Result(),
	}

	var got []byte

	got, err = result.DumpResponse([]string{`h1`})
	if err != nil {
		log.Fatal(`DumpResponse #1:`, err)
	}
	fmt.Printf("<<< DumpResponse:\n%s\n", got)

	result.ResponseDump = nil

	got, err = result.DumpResponse([]string{`h3`})
	if err != nil {
		log.Fatal(`DumpResponse #2:`, err)
	}
	fmt.Printf("<<< DumpResponse:\n%s", got)

}
Output:

<<< DumpResponse:
HTTP/1.1 200 OK
Connection: close
Content-Type: text/plain; charset=utf-8
H2: v2
H3: v3

Hello world!
<<< DumpResponse:
HTTP/1.1 200 OK
Connection: close
Content-Type: text/plain; charset=utf-8
H1: v1
H2: v2

Hello world!

Jump to

Keyboard shortcuts

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