webtest

package module
v0.5.10 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2019 License: MIT Imports: 7 Imported by: 0

README

CircleCI

go-webtest

features

examples

full test code is here, the test target handler is defined here

with webtest
import (
	"net/http"
	"testing"

	webtest "github.com/podhmo/go-webtest"
	"github.com/podhmo/go-webtest/jsonequal"
	"github.com/podhmo/go-webtest/tripperware"
	"github.com/podhmo/noerror"
)

func TestWithWebtest(t *testing.T) {
	c := webtest.NewClientFromHandler(http.HandlerFunc(Add))
	var want interface{}
	got, err := c.Post("/",
		webtest.WithJSON(bytes.NewBufferString(`{"values": [1,2,3]}`)),
		webtest.WithTripperware(
			tripperware.ExpectCode(t, 200),
			tripperware.GetExpectedDataFromSnapshot(t, &want),
		),
	)

	noerror.Must(t, err)
	defer func() { noerror.Must(t, got.Close()) }()
	noerror.Should(t,
		jsonequal.ShouldBeSame(
			jsonequal.From(got.JSONData()),
			jsonequal.From(want),
		),
	)
}
with try package (shortcut)
import (
	"net/http"
	"testing"

	webtest "github.com/podhmo/go-webtest"
	"github.com/podhmo/go-webtest/try"
)


func TestWithTry(t *testing.T) {
	c := webtest.NewClientFromHandler(http.HandlerFunc(Add))

	var want interface{}
	try.It{
		Code: 200,
		Want: &want,
		ModifyResponse: func(res webtest.Response) (got interface{}) {
			return res.JSONData()
		},
	}.With(t, c,
		"POST", "/",
		webtest.WithJSON(bytes.NewBufferString(`{"values": [1,2,3]}`)),
	)
}

If modify response is not needed, it is also ok, when the response does not include semi-random value (for example the value of now time).

c := webtest.NewClientFromHandler(http.HandlerFunc(Add))

var want interface{}
try.It{
	Code: 200,
	Want: &want,
}.With(t, c,
	"POST", "/",
	webtest.WithJSON(bytes.NewBufferString(`{"values": [1,2,3]}`)),
)
without-webtest (but snapshot testing)
import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"reflect"
	"testing"

	"github.com/podhmo/go-webtest/snapshot"
)

func TestWithoutWebtest(t *testing.T) {
	w := httptest.NewRecorder()
	req := httptest.NewRequest("POST", "/", bytes.NewBufferString(`{"values": [1,2,3]}`))
	req.Header.Set("Content-Type", "application/json")

	Add(w, req)
	res := w.Result()

	if res.StatusCode != 200 {
		b, _ := ioutil.ReadAll(res.Body)
		t.Fatalf("status code, want 200, but got %d\n response:%s", res.StatusCode, string(b))
	}

	var got interface{}
	decoder := json.NewDecoder(res.Body)
	if err := decoder.Decode(&got); err != nil {
		t.Fatal(err)
	}
	defer res.Body.Close()

	want := snapshot.Take(t, &got)
	if !reflect.DeepEqual(want, got) {
		t.Errorf(`want %s, but got %s`, want, got)
	}
}

the location of snapshot data

The snapshot data is saved in testdata/<test function name>.golden (e.g. testdata/TestHandler/try.golden) .

{
  "modifiedAt": "2019-09-07T21:40:30.70331035+09:00",
  "data": {
    "request": {
      "method": "POST",
      "path": "/"
    },
    "response": {
      "data": {
        "result": 6
      },
      "statusCode": 200
    }
  }
}

example output if tests are failed

Output examples.

✅ debug trace (not failed)
$ DEBUG=1 go test -v
2019/09/08 08:42:56 builtin debug trace is activated
=== RUN   TestHandler
=== RUN   TestHandler/plain
=== RUN   TestHandler/webtest
	Request : ------------------------------
	POST / HTTP/1.1
	Host: example.com
	Content-Type: application/json
	
	{"values": [1,2,3]}
	----------------------------------------
	Response: ------------------------------
	HTTP/1.1 200 OK
	Connection: close
	Content-Type: application/json
	
	{"result":6}
	----------------------------------------
=== RUN   TestHandler/try
	Request : ------------------------------
	POST / HTTP/1.1
	Host: example.com
	Content-Type: application/json
	
	{"values": [1,2,3]}
	----------------------------------------
	Response: ------------------------------
	HTTP/1.1 200 OK
	Connection: close
	Content-Type: application/json
	
	{"result":6}
	----------------------------------------
--- PASS: TestHandler (0.00s)
    --- PASS: TestHandler/plain (0.00s)
        snapshot.go:56: load snapshot data: "testdata/TestHandler/plain.golden"
    --- PASS: TestHandler/webtest (0.00s)
        snapshot.go:56: load snapshot data: "testdata/TestHandler/webtest.golden"
    --- PASS: TestHandler/try (0.00s)
        snapshot.go:56: load snapshot data: "testdata/TestHandler/try.golden"
PASS
ok  	github.com/podhmo/go-webtest	0.005s
❌ unexpected status
$ go test
--- FAIL: TestHandler (0.00s)
    --- FAIL: TestHandler/try (0.00s)
        snapshot.go:56: load snapshot data: "testdata/TestHandler/try.golden"
        integration_test.go:103: unexpected error, status code, got is "200 OK", but want is "201 Created"
            Response: ------------------------------
            HTTP/1.1 200 OK
            Connection: close
            Content-Type: application/json
            
            {"result":6}
            ----------------------------------------
            
FAIL
❌ unexpected response
$ go test
--- FAIL: TestHandler (0.00s)
    --- FAIL: TestHandler/try (0.00s)
        snapshot.go:56: load snapshot data: "testdata/TestHandler/try.golden"
        integration_test.go:105: on equal check: jsondiff, got and want is not same. (status=NoMatch)
            {
                "result": 10 => 6
            }
            
            left (got) :
            	{"result":10}
            right (want) :
            	{"result":6}
            
FAIL

sub packages

try

todo

snapshot

todo

snapshot/replace

todo

jsonequal

todo

testclient

todo

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MustParseQuery added in v0.2.0

func MustParseQuery(query string) url.Values

MustParseQuery :

Types

type Client

type Client struct {
	Internal Internal
}

Client :

func NewClientFromHandler

func NewClientFromHandler(handler http.Handler) *Client

NewClientFromHandler :

func NewClientFromTestServer

func NewClientFromTestServer(ts *httptest.Server) *Client

NewClientFromTestServer :

func NewClientFromURL added in v0.2.0

func NewClientFromURL(url string) *Client

NewClientFromURL :

func (*Client) Delete added in v0.5.1

func (c *Client) Delete(path string, options ...Option) (Response, error)

Delete :

func (*Client) Do

func (c *Client) Do(
	method string,
	path string,
	options ...Option,
) (Response, error)

Do :

func (*Client) DoFromRequest

func (c *Client) DoFromRequest(
	req *http.Request,
	options ...Option,
) (Response, error)

DoFromRequest :

func (*Client) Get added in v0.5.1

func (c *Client) Get(path string, options ...Option) (Response, error)

Get :

func (*Client) Head added in v0.5.1

func (c *Client) Head(path string, options ...Option) (Response, error)

Head :

func (*Client) Patch added in v0.5.1

func (c *Client) Patch(path string, options ...Option) (Response, error)

Patch :

func (*Client) Post added in v0.5.1

func (c *Client) Post(path string, options ...Option) (Response, error)

Post :

func (*Client) Put added in v0.5.1

func (c *Client) Put(path string, options ...Option) (Response, error)

Put :

type Config

type Config struct {
	BasePath     string
	Method       string
	ClientConfig *testclient.Config

	ModifyRequests []func(*http.Request) // request modifyRequests
}

Config :

func NewConfig

func NewConfig() *Config

NewConfig :

func (*Config) Copy

func (c *Config) Copy() *Config

Copy :

type Internal

type Internal interface {
	Do(req *http.Request, clientConfig *testclient.Config) (Response, error)
	NewRequest(method string, path string, clientConfig *testclient.Config) (*http.Request, error)
}

Internal :

type Option added in v0.4.0

type Option interface {
	Apply(*Config)
}

Option :

func WithBasePath

func WithBasePath(basePath string) Option

WithBasePath set base path

func WithForm

func WithForm(data url.Values) Option

WithForm setup as send form-data request

func WithJSON

func WithJSON(body io.Reader) Option

WithJSON setup as json request

func WithModifyRequest added in v0.3.0

func WithModifyRequest(modifyRequest func(*http.Request)) Option

WithModifyRequest adds request modifyRequest

func WithQuery added in v0.2.0

func WithQuery(query url.Values) Option

WithQuery :

func WithTripperware added in v0.5.0

func WithTripperware(wares ...tripperware.Ware) Option

WithTripperware with client side middleware for roundTripper

type Response

type Response = testclient.Response

Response :

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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