Help us shape the future of Go! Take the 2026 Go Developer Survey

httpclient

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Sep 26, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package httpclient puts *http.Client behind a one-method interface so that outbound calls can be faked in tests.

type OrderAPI struct {
	http httpclient.Client
}

api := OrderAPI{http: httpclient.New()}

In a test the same field takes the mock shipped with this package:

m := &httpclient.ClientMock{}
m.On("Do", mock.Anything).Return(resp, nil)

api := OrderAPI{http: m}

New returns a client backed by http.DefaultClient, which has no timeout. A server that accepts the connection and then never answers will block the calling goroutine indefinitely, so set a deadline on the request context before handing it to Do.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client interface {
	Do(req *http.Request) (*http.Response, error)
}

Client performs HTTP requests. It is the subset of *http.Client that calling code actually needs, which makes it substitutable by ClientMock in tests.

As with *http.Client, the caller closes the response body.

func New

func New() Client

New returns a Client backed by http.DefaultClient.

http.DefaultClient has no timeout, so a request that must not hang forever needs a deadline on its context.

Example

New wraps http.DefaultClient, which has no timeout, so the deadline has to come from the request context.

package main

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

	"github.com/diegodesousas/go-devkit/pkg/httpclient"
)

func main() {
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_, _ = fmt.Fprint(w, "pong")
	}))
	defer server.Close()

	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, server.URL, nil)
	if err != nil {
		panic(err)
	}

	resp, err := httpclient.New().Do(req)
	if err != nil {
		panic(err)
	}
	defer func() { _ = resp.Body.Close() }()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.StatusCode, string(body))

}
Output:
200 pong

type ClientMock

type ClientMock struct {
	mock.Mock
}

ClientMock is a testify mock implementing Client.

Do type-asserts the first return value, so the expectation has to supply something typed *http.Response even on the error path. A bare

m.On("Do", req).Return(nil, err)

panics with "interface conversion: interface {} is nil, not *http.Response". Write the typed nil instead:

m.On("Do", req).Return((*http.Response)(nil), err)
Example

ClientMock substitutes the real client in tests. Do type-asserts its first return value, so the error path needs a typed nil rather than a bare one.

package main

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

	"github.com/diegodesousas/go-devkit/pkg/httpclient"
	"github.com/stretchr/testify/mock"
)

func main() {
	m := &httpclient.ClientMock{}
	m.On("Do", mock.Anything).Return((*http.Response)(nil), context.DeadlineExceeded)

	var client httpclient.Client = m

	_, err := client.Do(httptest.NewRequest(http.MethodGet, "/ping", nil))
	fmt.Println(err)

}
Output:
context deadline exceeded

func (*ClientMock) Do

func (c *ClientMock) Do(req *http.Request) (*http.Response, error)

Jump to

Keyboard shortcuts

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