Documentation
¶
Overview ¶
Package webmock is a pure-Go (CGO-free) reimplementation of the deterministic core of Ruby's webmock gem — an HTTP request matcher, stub registry, and recorded-request history — without any Ruby runtime.
webmock lets a test declare stubs ("when a GET goes to www.example.com with these headers and body, answer 200 with this body") and then matches live requests against them, recording every request so the test can assert how many times an endpoint was hit. Everything webmock does around the wire — deciding whether a request matches a stub, picking the stubbed response, counting requests, refusing unstubbed traffic when the network is disabled — is deterministic and needs no interpreter, so it lives here as pure Go. The interception of the real HTTP transport is the host's job: rbgo binds this engine to its Net::HTTP replacement and feeds every outgoing request through Registry.Match.
It is the webmock engine for [go-embedded-ruby](https://github.com/go-embedded-ruby/ruby), but a standalone, reusable module — a sibling of go-ruby-openbao/openbao and go-ruby-net-http/net-http.
Value model ¶
A Request is the request under test (Method, URI, Headers, Body). A StubResponse is a canned answer (Status, Headers, Body). A Stub pairs a request matcher with an ordered list of behaviours (return a response, raise an error, time out), built fluently:
reg := webmock.NewRegistry()
reg.StubRequest("GET", "www.example.com").
With(webmock.Header("Accept", "application/json")).
ToReturn(webmock.StubResponse{Status: 200, Body: `{"ok":true}`})
resp, err := reg.Match(webmock.Request{
Method: "GET",
URI: "http://www.example.com/",
Headers: map[string][]string{"Accept": {"application/json"}},
})
// resp.Status == 200; err == nil
When no stub matches, Registry.Match returns a *NoStubError carrying a webmock-style diff (unless net connections have been re-enabled with Registry.AllowNetConnect, in which case it returns ErrNetConnectAllowed so the host can perform the real request). Registry.Requested and Registry.AssertRequested mirror the gem's assert_requested / have_requested.
Index ¶
- Variables
- func AllowNetConnect()
- func AssertRequested(method, uri string, times int, opts ...Option) error
- func DisableNetConnect()
- func Requested(method, uri string, opts ...Option) int
- func Reset()
- type AssertionError
- type NoStubError
- type Option
- func Block(fn func(Request) bool) Option
- func Body(s string) Option
- func BodyForm(fields map[string]string) Option
- func BodyRe(re *regexp.Regexp) Option
- func Header(name, value string) Option
- func HeaderRe(name string, re *regexp.Regexp) Option
- func Headers(h map[string]string) Option
- func Query(q map[string]string) Option
- func QueryValues(v url.Values) Option
- type RaiseError
- type Registry
- func (r *Registry) AllowNetConnect()
- func (r *Registry) AssertRequested(method, uri string, times int, opts ...Option) error
- func (r *Registry) DisableNetConnect()
- func (r *Registry) Match(req Request) (StubResponse, error)
- func (r *Registry) Register(s *Stub) *Stub
- func (r *Registry) Requested(method, uri string, opts ...Option) int
- func (r *Registry) RequestedRe(method string, re *regexp.Regexp, opts ...Option) int
- func (r *Registry) Requests() []Request
- func (r *Registry) Reset()
- func (r *Registry) StubRequest(method, uri string, opts ...Option) *Stub
- func (r *Registry) StubRequestRe(method string, re *regexp.Regexp, opts ...Option) *Stub
- type Request
- type Stub
- type StubResponse
Constants ¶
This section is empty.
Variables ¶
var Default = NewRegistry()
Default is the process-wide registry backing the package-level helpers, so a host can call StubRequest / Match / AssertRequested the way Ruby uses the global WebMock module. Tests that want isolation should use their own NewRegistry instead.
var ErrNetConnectAllowed = errors.New("webmock: no stub registered; real net connection allowed")
ErrNetConnectAllowed is returned by Registry.Match when no stub matches but real net connections have been enabled with Registry.AllowNetConnect. The host should perform the real request itself; this engine opens no socket.
var ErrTimeout = errors.New("webmock: stubbed request timed out")
ErrTimeout is returned by Registry.Match when the matched stub is a to_timeout stub. It mirrors the gem raising a timeout on the bound transport.
Functions ¶
func AllowNetConnect ¶
func AllowNetConnect()
AllowNetConnect enables passthrough of unstubbed requests on Default.
func AssertRequested ¶
AssertRequested asserts a request count on Default.
func DisableNetConnect ¶
func DisableNetConnect()
DisableNetConnect forbids unstubbed requests on Default.
Types ¶
type AssertionError ¶
AssertionError reports a request-count assertion mismatch, mirroring the gem's assert_requested failure message.
func (*AssertionError) Error ¶
func (e *AssertionError) Error() string
type NoStubError ¶
NoStubError is returned by Registry.Match when no registered stub matches a request and net connections are disabled. Its message reproduces webmock's "unregistered request" diff: the offending request, a suggested stub snippet, and the list of registered stubs.
func (*NoStubError) Error ¶
func (e *NoStubError) Error() string
type Option ¶
type Option func(*matcher)
Option is a .with(...) constraint applied to a stub or an assertion. Options mirror webmock's with(headers:, body:, query:) and block matchers.
func Block ¶
Block constrains the request with an arbitrary predicate, mirroring webmock's with { |req| ... } block matcher.
func BodyForm ¶
BodyForm constrains the request body to a hash of fields, decoded from the body as URL-encoded form data or JSON per the request's Content-Type.
func Query ¶
Query constrains the request query string to the given parameters, order-insensitively.
func QueryValues ¶
QueryValues constrains the request query string to the given url.Values, order-insensitively (allowing repeated keys).
type RaiseError ¶
type RaiseError struct {
Err error
}
RaiseError is returned by Registry.Match when the matched stub is a to_raise stub. It wraps the exception the stub was told to raise, so errors.Is / errors.Unwrap reach the underlying error.
func (*RaiseError) Error ¶
func (e *RaiseError) Error() string
func (*RaiseError) Unwrap ¶
func (e *RaiseError) Unwrap() error
Unwrap exposes the raised exception to errors.Is / errors.As.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds registered stubs, the recorded request history, and the net-connect policy. It is the deterministic engine a host drives: every intercepted request goes through Registry.Match. A Registry is safe for concurrent use.
func NewRegistry ¶
func NewRegistry() *Registry
NewRegistry returns an empty registry with net connections disabled, matching webmock's default of refusing unstubbed requests.
func (*Registry) AllowNetConnect ¶
func (r *Registry) AllowNetConnect()
AllowNetConnect re-enables passthrough of unstubbed requests, mirroring WebMock.allow_net_connect!.
func (*Registry) AssertRequested ¶
AssertRequested returns nil if method/uri was requested exactly times, or an *AssertionError otherwise, mirroring assert_requested(..., times:).
func (*Registry) DisableNetConnect ¶
func (r *Registry) DisableNetConnect()
DisableNetConnect forbids unstubbed requests, mirroring WebMock.disable_net_connect! (the default).
func (*Registry) Match ¶
func (r *Registry) Match(req Request) (StubResponse, error)
Match resolves a request against the registered stubs. On a match it records the request and returns the next stubbed outcome: a StubResponse, or one of ErrTimeout / a *RaiseError for to_timeout / to_raise stubs. When several stubs match, the most recently registered one wins (webmock semantics). With no match it returns ErrNetConnectAllowed if net connections are enabled, or a *NoStubError diff otherwise.
func (*Registry) Requested ¶
Requested counts recorded requests matching method/uri and the given constraints, mirroring a_request(...).should have_been_made / the count behind assert_requested.
func (*Registry) RequestedRe ¶
RequestedRe is like Registry.Requested but matches the URI by regexp.
func (*Registry) Reset ¶
func (r *Registry) Reset()
Reset clears stubs and history, mirroring WebMock.reset!.
func (*Registry) StubRequest ¶
StubRequest builds and registers a stub, mirroring stub_request(method, uri).
type Request ¶
Request is an outgoing HTTP request presented to the registry for matching. It is the value model a host (rbgo) fills in from its intercepted Net::HTTP request. Header names are matched case-insensitively, mirroring HTTP and the webmock gem.
type Stub ¶
type Stub struct {
// contains filtered or unexported fields
}
Stub is a registered request matcher paired with an ordered list of behaviours. Successive matches walk the list; once exhausted the last behaviour repeats, mirroring webmock's sequential to_return semantics.
func NewStub ¶
NewStub builds an unregistered stub for method (":any" via "" or "ANY") and a string URI pattern, with optional .with(...) constraints. Register it on a Registry with Registry.Register, or use Registry.StubRequest to do both.
func NewStubRe ¶
NewStubRe is like NewStub but matches the whole request URI against a regexp, mirroring stub_request(:any, /regex/).
func StubRequest ¶
StubRequest builds and registers a stub on Default.
func StubRequestRe ¶
StubRequestRe registers a regexp-URI stub on Default.
func (*Stub) ToRaise ¶
ToRaise appends a behaviour that makes Registry.Match return a *RaiseError wrapping err, mirroring to_raise.
func (*Stub) ToReturn ¶
func (s *Stub) ToReturn(resps ...StubResponse) *Stub
ToReturn appends one or more responses. Called with several responses (or chained) it builds a sequence returned on successive matches; called with none it appends a default empty 200. A zero Status defaults to 200.
func (*Stub) ToTimeout ¶
ToTimeout appends a behaviour that makes Registry.Match return ErrTimeout, mirroring to_timeout.
type StubResponse ¶
StubResponse is a canned response a stub returns when its matcher fires. It mirrors webmock's to_return(status:, body:, headers:).
