checkhttpmock

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jun 18, 2021 License: GPL-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Helper package to add more functions to httpmock (github.com/jarcoal/httpmock)

Features: - RegisterQueryMapResponder form query based based on a QueryMap - ActivateRecorder to record HTTP requests during the development of tests and examples

Example
package main

import (
	"bytes"
	"fmt"
	"github.com/NETWAYS/go-check/http/mock"
	"github.com/jarcoal/httpmock"
	"io/ioutil"
	"net/http"
)

func main() {
	// Activate httpmock as normal
	httpmock.Activate()
	defer httpmock.DeactivateAndReset()

	// Use any normal responder
	httpmock.RegisterResponder("GET", "https://example.com/test.json",
		func(request *http.Request) (*http.Response, error) {
			return httpmock.NewStringResponse(200, `{"allgood":true}`), nil
		})

	req, _ := http.NewRequest("GET", "https://example.com/test.json", nil) //nolint:noctx
	requestAndDump(req)

	// Use additional responders
	checkhttpmock.RegisterQueryMapResponder("POST", "https://exampleapi.com/",
		checkhttpmock.QueryMap{
			"test=1": "test.json",
		})

	req, _ = http.NewRequest("POST", "https://exampleapi.com/", bytes.NewBufferString("test=1")) //nolint:noctx
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	requestAndDump(req)

}

func requestAndDump(req *http.Request) {
	resp, err := http.DefaultTransport.RoundTrip(req)
	if err != nil {
		panic(err)
	}

	defer resp.Body.Close()

	data, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(data))
}
Output:

{"allgood":true}
{"example":true}

Index

Examples

Constants

View Source
const TestData = "./testdata"

Where response data is stored, relative to the package being tested

Variables

This section is empty.

Functions

func NewQueryMapResponder

func NewQueryMapResponder(queryMap QueryMap) func(request *http.Request) (*http.Response, error)

Return a responder function for httpmock, to return different results based on a QueryMap

Queries from the QueryMap are matched partially and the response is read from `./testdata`

func RegisterQueryMapResponder

func RegisterQueryMapResponder(method, url string, queryMap QueryMap)

Register a NewQueryMapResponder with httpmock

See QueryMap and NewQueryMapResponder

Types

type QueryMap

type QueryMap map[string]string

Mapping a partial form request to a response

The response will be expected and read from the local testdata directory of your package.

	QueryMap{
 	"test=1": "response.json",
	}

type Record

type Record struct {
	URL    string
	Method string
	Query  string
	Status string
	Body   string
}

Data structure to store information about a http.Request and http.Response in a simplified way

func NewRecord

func NewRecord(request *http.Request) (r *Record)

Build a new Record from an http.Request

func (*Record) Complete

func (r *Record) Complete(response *http.Response)

Update the Record with a http.Response to get Body and Status

func (Record) EmitYAML

func (r Record) EmitYAML(w io.Writer) (err error)

Write a YAML representation of the Record to an io.Writer

type Recorder

type Recorder struct {
	RecordFile string
	Writer     io.Writer
}

Helper to record http.Response and http.Request for httpmock when no responser was found

var (
	CurrentRecorder *Recorder
	// Default storage location for the recorded data
	RecordFile = TestData + "/httpmock-record.yml"
)

func ActivateRecorder

func ActivateRecorder() (rec *Recorder)

Activate a Recorder and set it as noResponder with httpmock

Usually you would use this during developing unit tests, and not for finished tests.

By default records to RecordFile

Example
package main

import (
	"fmt"
	"github.com/NETWAYS/go-check/http/mock"
	"github.com/jarcoal/httpmock"
	"io"
	"io/ioutil"
	"net/http"
	"os"
)

func main() {
	// Activate the normal httpmock
	httpmock.Activate()
	defer httpmock.DeactivateAndReset()

	// Activate recorder
	_ = os.Remove(checkhttpmock.RecordFile) // Remove any prior recording
	checkhttpmock.ActivateRecorder()

	// We don't set any mock examples here
	//httpmock.RegisterResponder("GET", "http://localhost:8080/test",
	//	func(request *http.Request) (*http.Response, error) {
	//		return httpmock.NewStringResponse(200, "Hello World"), nil
	//	})

	// Start a simple HTTP server
	runHTTP()

	// Do any HTTP request
	resp, err := http.Get("http://localhost:64888/test") // nolint:noctx
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Print response body
	data, _ := ioutil.ReadAll(resp.Body)
	fmt.Printf("%s\n", data)

	// Print recording
	data, _ = ioutil.ReadFile(checkhttpmock.RecordFile)
	fmt.Printf("%s\n", data)

	_ = resp.Body.Close()

}

func runHTTP() {
	http.HandleFunc("/test", func(w http.ResponseWriter, req *http.Request) {
		_, _ = io.WriteString(w, `Hello World`)
	})

	go http.ListenAndServe(":64888", nil) //nolint:errcheck
}
Output:

Hello World
---
url: http://localhost:64888/test
method: GET
query: ""
status: 200 OK
body: Hello World

func (*Recorder) Respond

func (rec *Recorder) Respond(request *http.Request) (response *http.Response, err error)

Handle http.request for httpmock, and execute a real HTTP connection using httpmock.InitialTransport

Recording and returning the real http.Response

Jump to

Keyboard shortcuts

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