httpmock

repository·v1·Indexed 24 days ago

https://github.com/jarcoal/httpmock

A Go library for mocking HTTP responses from external resources during testing. It intercepts outgoing HTTP requests and returns predefined responses to enable isolated unit and integration testing. Features include exact and regexp URL matching, custom function responders, request body and header matchers, and support for response sequencing, delays, and call count tracking. Compatible with Go versions 1.16 to 1.26.

Tokens
6.6K
Snippets
15
Records
41
Agent score
84%

What's inside httpmock

  1. How httpmock matches URLs

    v1

    When a request is intercepted, httpmock checks responders against the following URL variations in order. The first match stops the search:

    1. The original URL (including query params).
    2. The URL with query parameters sorted alphabetically.
    3. The URL without query parameters.
    4. The path only (without scheme and host) using the original query params.
    5. The path only (without scheme and host) using sorted query params.
    6. The path only.

    If no standard responder matches, httpmock then checks regexp responders in the same order.

  2. Integrate httpmock with Resty and Ginkgo

    v1
    If you are using a custom HTTP client like resty, you must use httpmock.ActivateNonDefault(client.GetClient()) to ensure httpmock intercepts requests made by that specific client instance.
  3. Install httpmock

    v1

    To use httpmock, import it into your Go files. The v1 branch should be used. Running go mod tidy or go test will automatically populate your go.mod with the latest release.

    Supported Go versions: 1.16 to 1.26.

    import "github.com/jarcoal/httpmock"
  4. Integrate httpmock with Ginkgo

    v1

    When using the Ginkgo testing framework, use BeforeSuite, BeforeEach, and AfterSuite to manage the lifecycle of the mock server.

    • httpmock.Activate(): Starts blocking HTTP requests.
    • httpmock.Reset(): Clears all registered responders.
    • httpmock.DeactivateAndReset(): Stops blocking and clears responders.
  5. Basic usage of httpmock

    v1

    To start mocking, call httpmock.Activate(t) within your test. You can then register responders for specific HTTP methods and URLs.

    httpmock supports:

    • Exact URL matching: Provide the full URL.
    • Regexp matching: Use the =~ prefix in the URL string to indicate a regular expression.

    You can also track call counts using httpmock.GetTotalCallCount() or httpmock.GetCallCountInfo() to verify how many times specific endpoints were hit.

    func TestFetchArticles(t *testing.T) {
      httpmock.Activate(t)
    
      // Exact URL match
      httpmock.RegisterResponder("GET", "https://api.mybiz.com/articles",
        httpmock.NewStringResponder(200, `[{"id": 1, "name": "My Great Article"}]`))
    
      // Regexp match
      httpmock.RegisterResponder("GET", `=~^https://api\.mybiz\.com/articles/id/\d+\z`,
        httpmock.NewStringResponder(200, `{"id": 1, "name": "My Great Article"}`))
    
      // ... perform requests ...
    
      // get count info
      httpmock.GetTotalCallCount()
      info := httpmock.GetCallCountInfo()
      _ = info["GET https://api.mybiz.com/articles"]
    }
  6. What is a Responder and how to use it

    v1

    A Responder is a callback function type used to mock HTTP responses. It receives an *http.Request and returns an *http.Response and an error.

    type Responder func(*http.Request) (*http.Response, error)

    You can create responders using various helper functions like NewStringResponder, NewBytesResponder, or NewJsonResponder, and then register them with httpmock to intercept outgoing requests.

    type Responder func(*http.Request) (*http.Response, error)
  7. Initialize the mock environment with Activate

    v1

    To intercept HTTP requests made via http.DefaultClient, call Activate. If you pass a testing.TB object (like *testing.T), httpmock will automatically call DeactivateAndReset when the test finishes.

    Use Activate in a test function to enable mocks for that specific test, or in an init() function to enable mocks for the entire package.

    func TestFetchArticles(t *testing.T) {
    	httpmock.Activate(t)
    	// all http requests using http.DefaultTransport will now be intercepted
    }
  8. Activate and Deactivate the mock environment

    v1

    To use httpmock, you must first activate the mock environment. This intercepts HTTP calls made via http.DefaultClient or http.DefaultTransport.

    • Activate(): Starts the mock environment. It is recommended to use t.Cleanup(httpmock.Deactivate) immediately after activation in tests to ensure the environment is shut down when the test finishes.
    • Deactivate(): Shuts down the mock environment and restores the original transports for all clients that were overridden using ActivateNonDefault.
    • DeactivateAndReset(): A convenience method that calls both Deactivate() and Reset(). This is useful for cleaning up both the environment and the registered mocks/counters.
    • Reset(): Removes all registered mocks and zeroes out call counters, but keeps the mock environment active.
    func TestFetchArticles(t *testing.T) {
      httpmock.Activate()
      t.Cleanup(httpmock.Deactivate)
    
      // when this test ends, the mock environment will close
    }
  9. Register advanced responders and matchers

    v1

    For more complex scenarios, httpmock provides several advanced capabilities:

    • Custom Function Responders: Pass a function func(req *http.Request) (*http.Response, error) to RegisterResponder to implement dynamic logic.
    • Regexp Submatches: Use httpmock.MustGetSubmatchAsUint(req, index) to extract values (like IDs) captured in a regex URL pattern.
    • Matcher Responders: Use httpmock.RegisterMatcherResponder combined with matchers like httpmock.BodyContainsString(string) to trigger specific responses based on request body content.
    • Response Helpers:
      • httpmock.NewJsonResponse(status, data): Returns a JSON response with application/json content-type.
      • httpmock.NewStringResponder(status, body): Returns a plain string response.
      • httpmock.NewStringResponse(status, body): Used within custom functions to return a response.
    // Example: Using regexp submatches and custom logic
    httpmock.RegisterResponder("GET", `=~^https://api\.mybiz\.com/articles/id/(\d+)\z`,
      func(req *http.Request) (*http.Response, error) {
        id := httpmock.MustGetSubmatchAsUint(req, 1)
        return httpmock.NewJsonResponse(200, map[string]interface{}{
          "id":   id,
          "name": "My Great Article",
        })
      })
    
    // Example: Matching based on request body
    httpmock.RegisterMatcherResponder("POST", "https://api.mybiz.com/articles",
      httpmock.BodyContainsString(`"type":"toy"`),
      httpmock.NewStringResponder(400, `{"reason":"Invalid article type"}`))
  10. Configure MockTransport behavior

    v1
    The MockTransport struct provides a DontCheckMethod field. By default, if you register a responder using a lowercase method (e.g., get instead of GET), httpmock will panic to alert you of the mistake. Setting DontCheckMethod: true disables this check.
  11. Control httpmock status with GONOMOCKS environment variable

    v1

    The behavior of httpmock.Disabled() is driven by the GONOMOCKS environment variable.

    • To disable httpmock (making Disabled() return true), set GONOMOCKS to any value.
    • To enable httpmock (making Disabled() return false), ensure GONOMOCKS is unset or empty.
  12. Print the filename instead of file contents when using httpmock.File

    v1

    Since httpmock.File implements the fmt.Stringer interface, standard formatting functions like fmt.Printf("%s\n", file) will output the contents of the file.

    To print the actual filename, you must explicitly cast the File type to a string.

    file := httpmock.File("file.txt")
    
    // Prints the content of file "file.txt"
    fmt.Printf("file: %s\n", file)
    
    // Prints the filename "file.txt"
    fmt.Printf("file: %s\n", string(file))