Documentation
¶
Overview ¶
Package httpclienttest provides testing utilities for HTTP client code.
Makes testing HTTP interactions easier, more reliable, and less dependent on external services. Follows common testing patterns like spies, stubs, and mocks for unit test verification.
Index ¶
- type DoerSpy
- type DoerSpyRecord
- type DoerStub
- type DoerStubCall
- type RequestMatcher
- type RequestMatcherBuilder
- func (b *RequestMatcherBuilder) BodyForm(compareWith url.Values, strict bool) *RequestMatcherBuilder
- func (b *RequestMatcherBuilder) BodyJSON(compareWith any, getDest func() any, strict bool) *RequestMatcherBuilder
- func (b *RequestMatcherBuilder) HeadersContains(headers http.Header) *RequestMatcherBuilder
- func (b *RequestMatcherBuilder) MatchRequest(req *http.Request) error
- func (b *RequestMatcherBuilder) Method(method string) *RequestMatcherBuilder
- func (b *RequestMatcherBuilder) URLHost(host string) *RequestMatcherBuilder
- func (b *RequestMatcherBuilder) URLPath(path string) *RequestMatcherBuilder
- func (b *RequestMatcherBuilder) URLQueryParamsContains(params url.Values) *RequestMatcherBuilder
- type Server
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DoerSpy ¶
type DoerSpy struct {
// contains filtered or unexported fields
}
DoerSpy implements httpclient.Doer and records all calls to the underlying Doer. Useful for verifying specific HTTP requests were made. Safe for concurrent use.
func NewDoerSpy ¶
func NewDoerSpy(doer httpclient.Doer) *DoerSpy
NewDoerSpy creates DoerSpy wrapping the provided Doer. Forwards all requests while recording inputs and outputs for inspection.
func (*DoerSpy) Calls ¶
func (d *DoerSpy) Calls() []DoerSpyRecord
Calls returns a copy of all recorded calls made through this spy and clears the internal call history. Each call returns a fresh slice, making it safe to call concurrently. The returned slice contains calls in the order they were made.
type DoerSpyRecord ¶
type DoerSpyRecord struct {
InputRequest *http.Request
OutputResponse *http.Response
OutputError error
}
DoerSpyRecord represents a single recorded HTTP request/response interaction. It captures the complete input and output of one call to the Do method, including any error that may have occurred during the request.
type DoerStub ¶
type DoerStub struct {
// contains filtered or unexported fields
}
DoerStub implements httpclient.Doer and returns pre-configured responses without making actual HTTP requests. Useful for controlling exact responses or testing error conditions.
Two modes: strict order (exact consumption order) or flexible order (first match). Safe for concurrent use.
func NewDoerStub ¶
func NewDoerStub(calls []DoerStubCall, strictOrder bool) *DoerStub
NewDoerStub creates DoerStub with provided call configurations. Calls slice defines responses for matching requests.
If strictOrder is true, calls consumed in exact order, non-matches error. If false, first matching call (or no matcher) used and consumed. See DoerStubCall for configuring individual responses.
func (*DoerStub) Do ¶
Do implements httpclient.Doer by returning pre-configured responses based on the configured DoerStubCall slice. The behavior depends on the strictOrder setting:
In strict order mode (strictOrder=true):
- calls are processed in the exact order they were configured
- if a call has a RequestMatcher and the request doesn't match, an error is returned
- if a call has no RequestMatcher, it matches any request
In flexible order mode (strictOrder=false):
- calls are searched in order until a matching one is found
- non-matching calls are skipped
- the first matching call (or call without a matcher) is used and consumed
Returns an error if no configured calls remain or if no call matches the request. This method is safe for concurrent use.
func (*DoerStub) RemainingCalls ¶
func (d *DoerStub) RemainingCalls() []DoerStubCall
RemainingCalls returns a copy of all DoerStubCall configurations that have not yet been consumed by calls to Do. This is useful in tests to verify that all expected HTTP calls were actually made. The returned slice is a copy and safe to modify. This method is safe for concurrent use.
type DoerStubCall ¶
type DoerStubCall struct {
Matcher RequestMatcher
Response *http.Response
Error error
}
DoerStubCall defines the configuration for a single stubbed HTTP call. It consists of an optional RequestMatcher to determine if an incoming request should use this configuration, and a Response/Error pair to return.
If Matcher is nil, this call configuration will match any request. If Matcher is set, the incoming request must pass all the matcher's assertions for this configuration to be used.
type RequestMatcher ¶
RequestMatcher defines an interface for validating HTTP requests against predefined criteria. Implementations should return nil if the request matches all expected conditions, or a descriptive error if any condition fails. This interface is commonly used with DoerStub to ensure that stubbed responses are only returned for expected requests.
type RequestMatcherBuilder ¶
type RequestMatcherBuilder struct {
// contains filtered or unexported fields
}
RequestMatcherBuilder provides a fluent interface for building complex HTTP request assertions. It implements the RequestMatcher interface and allows chaining multiple validation criteria such as HTTP method, URL components, headers, and body content. Each method adds a new assertion that will be checked when MatchRequest is called.
func NewRequestMatcherBuilder ¶
func NewRequestMatcherBuilder() *RequestMatcherBuilder
NewRequestMatcherBuilder creates a new empty RequestMatcherBuilder with no assertions. Use the builder's methods to add specific validation criteria for HTTP requests.
func (*RequestMatcherBuilder) BodyForm ¶
func (b *RequestMatcherBuilder) BodyForm(compareWith url.Values, strict bool) *RequestMatcherBuilder
BodyForm adds an assertion that the request body contains form data matching the provided url.Values. The request's Content-Type should be "application/x-www-form-urlencoded". If strict is true, the form data must match exactly with no additional fields. If strict is false, additional fields in the request are allowed.
func (*RequestMatcherBuilder) BodyJSON ¶
func (b *RequestMatcherBuilder) BodyJSON(compareWith any, getDest func() any, strict bool) *RequestMatcherBuilder
BodyJSON adds an assertion that the request body contains JSON data that can be unmarshalled into the type returned by getDest() and matches compareWith exactly. The getDest function should return a new instance of the expected type for unmarshalling. If strict is true, the JSON must not contain any fields not present in the target type. If strict is false, additional JSON fields are ignored during unmarshalling.
func (*RequestMatcherBuilder) HeadersContains ¶
func (b *RequestMatcherBuilder) HeadersContains(headers http.Header) *RequestMatcherBuilder
HeadersContains adds an assertion that the request headers must contain all the provided header key-value pairs. Additional headers in the request are allowed. Header names are case-insensitive, but values must match exactly including order.
func (*RequestMatcherBuilder) MatchRequest ¶
func (b *RequestMatcherBuilder) MatchRequest(req *http.Request) error
MatchRequest implements the RequestMatcher interface by running all configured assertions against the provided HTTP request. It returns nil if all assertions pass, or a combined error containing details of all failed assertions.
func (*RequestMatcherBuilder) Method ¶
func (b *RequestMatcherBuilder) Method(method string) *RequestMatcherBuilder
Method adds an assertion that the HTTP request method must exactly match the provided method. The comparison is case-sensitive (e.g., "GET", "POST", "PUT").
func (*RequestMatcherBuilder) URLHost ¶
func (b *RequestMatcherBuilder) URLHost(host string) *RequestMatcherBuilder
URLHost adds an assertion that the request URL's host component must exactly match the provided host string. This includes the hostname and optional port (e.g., "example.com:8080").
func (*RequestMatcherBuilder) URLPath ¶
func (b *RequestMatcherBuilder) URLPath(path string) *RequestMatcherBuilder
URLPath adds an assertion that the request URL's path component must exactly match the provided path string. The path should include the leading slash (e.g., "/api/users").
func (*RequestMatcherBuilder) URLQueryParamsContains ¶
func (b *RequestMatcherBuilder) URLQueryParamsContains(params url.Values) *RequestMatcherBuilder
URLQueryParamsContains adds an assertion that the request URL's query parameters must contain all the provided key-value pairs. Additional query parameters in the request are allowed. The values for each key must match exactly, including order.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server provides a testing utility that creates temporary HTTP servers for validating HTTP client behavior. It combines request assertion with response generation, allowing tests to verify that clients make expected requests and handle responses correctly. The server automatically starts and stops a httptest.Server for each assertion.
func NewServer ¶
func NewServer(do func(serverAddress url.URL, serverDoer httpclient.Doer, checkResponseFunc any) error) *Server
NewServer creates a new Server with the provided request execution function. The do function should contain the code under test that makes HTTP requests. It receives the temporary server's URL, an HTTP client (typically httptest server's client), and an optional checkResponseFunc parameter that can be used for additional response validation. The do function should return an error if the HTTP request or response handling fails.
func (*Server) AssertRequest ¶
func (srv *Server) AssertRequest(requestExpectations RequestMatcher, writeResponse func(http.ResponseWriter) error, checkResponseFunc any) error
AssertRequest creates a temporary HTTP server, executes the configured request function, and validates both the incoming request and outgoing response. It performs three main steps:
- creates a httptest.Server that validates incoming requests using requestExpectations
- calls the configured do function with the server URL and client
- uses writeResponse to generate the HTTP response sent back to the client
The requestExpectations RequestMatcher validates that the incoming HTTP request meets all specified criteria (method, headers, body, etc.).
The writeResponse function is responsible for writing the HTTP response, including status code, headers, and body. It should return an error if response writing fails.
The checkResponseFunc parameter is passed through to the do function and can be used for additional response validation logic specific to the test case.
Returns an error if request validation fails, response writing fails, or the do function returns an error.