RepoPilotOpen in app →

bblimke/webmock

Library for stubbing and setting expectations on HTTP requests in Ruby.

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 8w ago
  • 17 active contributors
  • Distributed ownership (top contributor 34% of recent commits)
Show 3 more →
  • MIT licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/bblimke/webmock)](https://repopilot.app/r/bblimke/webmock)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/bblimke/webmock on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: bblimke/webmock

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/bblimke/webmock shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 8w ago
  • 17 active contributors
  • Distributed ownership (top contributor 34% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live bblimke/webmock repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/bblimke/webmock.

What it runs against: a local clone of bblimke/webmock — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in bblimke/webmock | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 83 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>bblimke/webmock</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of bblimke/webmock. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/bblimke/webmock.git
#   cd webmock
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of bblimke/webmock and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "bblimke/webmock(\\.git)?\\b" \\
  && ok "origin remote is bblimke/webmock" \\
  || miss "origin remote is not bblimke/webmock (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "lib/webmock.rb" \\
  && ok "lib/webmock.rb" \\
  || miss "missing critical file: lib/webmock.rb"
test -f "lib/webmock/http_lib_adapters/http_lib_adapter.rb" \\
  && ok "lib/webmock/http_lib_adapters/http_lib_adapter.rb" \\
  || miss "missing critical file: lib/webmock/http_lib_adapters/http_lib_adapter.rb"
test -f "lib/webmock/request_stub.rb" \\
  && ok "lib/webmock/request_stub.rb" \\
  || miss "missing critical file: lib/webmock/request_stub.rb"
test -f "lib/webmock/request_pattern.rb" \\
  && ok "lib/webmock/request_pattern.rb" \\
  || miss "missing critical file: lib/webmock/request_pattern.rb"
test -f "lib/webmock/stub_registry.rb" \\
  && ok "lib/webmock/stub_registry.rb" \\
  || miss "missing critical file: lib/webmock/stub_registry.rb"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 83 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~53d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/bblimke/webmock"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

WebMock is a Ruby library that stubs HTTP requests at the HTTP client library level, allowing developers to test code that makes HTTP calls without hitting real servers. It supports matching requests by method, URI, headers, and body across 15+ HTTP client libraries (Net::HTTP, HTTParty, Typhoeus, Excon, etc.), and provides RSpec/Minitest/Cucumber integrations for setting expectations on HTTP interactions. Modular architecture centered on lib/webmock/http_lib_adapters/ directory with one adapter per HTTP library (e.g., net_http.rb, typhoeus_hydra_adapter.rb, http_rb_adapter.rb), paired with a registry (http_lib_adapter_registry.rb). Core stubbing logic in request_stub.rb and request_registry.rb, with RSpec/Minitest integration modules at lib/webmock/rspec.rb and lib/webmock/minitest.rb.

👥Who it's for

Ruby developers writing unit and integration tests who need to mock external HTTP dependencies without modifying test code when switching HTTP libraries. Common users: Rails developers, gem maintainers, teams testing microservices.

🌱Maturity & risk

Highly mature and production-ready. The project has been actively maintained for 10+ years with extensive CI coverage (GitHub Actions CI.yml workflow), comprehensive test suite across multiple Ruby versions (2.6–4.0 and JRuby), and recent activity visible in the CHANGELOG. It's widely used in the Ruby community.

Low risk for core functionality, but dependent on maintaining compatibility with 15+ evolving HTTP libraries (Curb, Typhoeus, Excon, etc.) which could create maintenance burden. Single primary maintainer (bblimke) is typical for mature gems but concentrates decision-making. No evidence of abandoned dependencies in the file list.

Active areas of work

Unable to determine from file structure alone—would require checking the Git log, open issues, and CI status. Typical active maintenance likely includes compatibility updates for new Ruby versions and bug fixes across adapters.

🚀Get running

git clone https://github.com/bblimke/webmock.git
cd webmock
bundle install
rake

This uses Bundler (Gemfile present) and Rake for test execution. The .gemtest file indicates gem-based testing support.

Daily commands:

rake test          # Run full test suite
rake spec          # Run RSpec specs
rspec spec/        # Run specific spec file

Development workflow uses standard Ruby Rake tasks defined in Rakefile.

🗺️Map of the codebase

  • lib/webmock.rb — Main entry point that loads and initializes all WebMock components; every integration must pass through here.
  • lib/webmock/http_lib_adapters/http_lib_adapter.rb — Base class defining the adapter interface; understanding this is essential for supporting new HTTP libraries.
  • lib/webmock/request_stub.rb — Core abstraction for HTTP request stubs; central to how WebMock intercepts and responds to requests.
  • lib/webmock/request_pattern.rb — Pattern matching logic for incoming requests; critical for understanding how stub matching works.
  • lib/webmock/stub_registry.rb — Registry managing active stubs and their lifecycle; essential for state management and stub lookup.
  • lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb — Registry of all supported HTTP library adapters; required reading for adding new HTTP client support.
  • lib/webmock/api.rb — Public API surface exposing stub, expect, and verify methods; defines the user-facing contract.

🛠️How to make changes

Add support for a new HTTP library

  1. Create a new adapter class inheriting from HttpLibAdapter in lib/webmock/http_lib_adapters/ (lib/webmock/http_lib_adapters/my_http_lib_adapter.rb)
  2. Implement required methods: enabled?, perform_request, and any hooks needed to intercept requests (lib/webmock/http_lib_adapters/http_lib_adapter.rb)
  3. Register the adapter in HttpLibAdapterRegistry#load_adapters method (lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb)
  4. Create acceptance tests in spec/acceptance/my_http_lib/ following the pattern of existing adapters (spec/acceptance/my_http_lib/my_http_lib_spec.rb)

Add a new request matching criterion

  1. Add matching logic to RequestPattern class (e.g., new method like #matches_custom_field?) (lib/webmock/request_pattern.rb)
  2. Extend RequestSignature to normalize the new field from incoming requests (lib/webmock/request_signature.rb)
  3. Add a DSL method to the API for users to specify the criterion (e.g., custom_header:) (lib/webmock/api.rb)
  4. Write tests in spec/ validating the new matcher works across adapters (spec/acceptance/shared/common_behaviors.rb)

Add a custom matcher for complex request matching

  1. Create a new matcher class in lib/webmock/matchers/ inheriting from existing matcher patterns (lib/webmock/matchers/my_custom_matcher.rb)
  2. Implement ==, description, and any required comparison logic matching the Matcher interface (lib/webmock/matchers/hash_argument_matcher.rb)
  3. Export the matcher in lib/webmock.rb so users can require and use it (lib/webmock.rb)
  4. Add usage examples in acceptance tests showing how the matcher works with different HTTP libraries (spec/acceptance/net_http/net_http_spec.rb)

Modify response behavior (delays, streaming, callbacks)

  1. Extend Response class with new attributes and methods for the desired behavior (lib/webmock/response.rb)
  2. Update RequestStub to expose new DSL methods (e.g., to_return(delay: 1.5)) (lib/webmock/request_stub.rb)
  3. Modify adapter implementations to respect the new response behavior when returning to the HTTP client (lib/webmock/http_lib_adapters/net_http.rb)
  4. Write integration tests verifying the behavior works across multiple HTTP libraries (spec/acceptance/shared/callbacks.rb)

🔧Why these technologies

  • Adapter pattern for HTTP libraries — WebMock supports 10+ different Ruby HTTP clients (Net::HTTP, httpclient, Curb, etc.); adapters isolate library-specific interception logic from core matching/stubbing engine
  • Method interception / monkey-patching — Must intercept HTTP calls at the HTTP library level without requiring code changes; achieved by replacing key methods in target libraries when adapter is loaded
  • URI normalization and smart matching — HTTP URIs can be represented in multiple equivalent forms (encoded/non-encoded, path ordering); normalization ensures consistent matching across representations
  • Signature-based request matching — Stubs match against normalized RequestSignature objects derived from incoming requests; enables flexible pattern matching on method, URI, headers, and body
  • Registry pattern for stubs and adapters

🪤Traps & gotchas

Global state: WebMock uses a global registry (request_registry.rb, callback_registry.rb), requiring explicit WebMock.reset! between tests or test leakage occurs—watch for forgotten setup/teardown. HTTP library version coupling: Adapters are tightly bound to specific HTTP library internals; major version upgrades of dependencies (Typhoeus, Excon) can break adapters without immediate webmock release. Net::HTTP monkey-patching: The core adapter directly patches Net::HTTP module internals—other gems patching the same methods can conflict. Encoding sensitivity: Smart URI/header matching uses intelligent normalization but edge cases with non-ASCII, percent-encoding, and HTTP/2 can surprise—test encoding explicitly.

🏗️Architecture

💡Concepts to learn

  • HTTP client adapter pattern — WebMock's entire design pivots on the Adapter pattern (lib/webmock/http_lib_adapters/) to intercept requests from different HTTP libraries uniformly—understanding this pattern is essential to onboard on the codebase
  • Monkey-patching and method interception — WebMock stubs HTTP calls by monkey-patching HTTP library internals (e.g., Net::HTTP#request) at runtime—this is non-obvious Ruby metaprogramming that risks conflicts but avoids test code changes
  • Request matching with smart normalization — lib/webmock/request_pattern.rb implements intelligent URI and header matching that handles percent-encoding, header case-insensitivity, and query parameter reordering—critical for realistic stub matching without brittle tests
  • Global state management via registries — WebMock relies on global RequestRegistry and CallbackRegistry to track stubs and verify interactions—understanding when state is reset (test setup/teardown) prevents test leakage
  • Test doubles (stubs vs. mocks vs. expectations) — WebMock blurs lines between stubs (pre-configured responses), mocks (objects tracking calls), and expectations (post-test assertions)—you configure stubs with stub_request, then verify with have_requested expectations
  • Rack response normalization — lib/webmock/rack_response.rb converts Rack-style responses [status, headers, body] to WebMock Response objects, enabling integration with Rack/Rails test helpers alongside HTTP client stubbing
  • Request body diffing for error messages — lib/webmock/request_body_diff.rb generates readable diffs when request bodies don't match expectations—improves test failure clarity, especially critical for JSON/XML payloads
  • vcr/vcr — Complementary Ruby gem that records/replays HTTP interactions as cassettes instead of stubbing; many teams use both for integration tests
  • geemus/excon — One of the 15+ HTTP libraries WebMock supports; understanding its internals is essential for maintaining the Excon adapter
  • httprb/http — The modern 'http' gem that WebMock actively supports via dedicated adapter at lib/webmock/http_lib_adapters/http_rb_adapter.rb and http_rb/ subdirectory
  • typhoeus/typhoeus — High-performance HTTP client with Hydra (parallel requests) that WebMock supports; adapter at lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb
  • rspec/rspec-core — WebMock's primary integration target; deeply integrated via lib/webmock/rspec/ and requires understanding RSpec matchers and hooks

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive integration tests for all HTTP adapter implementations

The repo supports 10+ HTTP client libraries (Net::HTTP, Excon, Typhoeus, HTTP.rb, Httpclient, Curb, Patron, Manticore, EM-HTTP, Async-HTTP) across lib/webmock/http_lib_adapters/, but there's no evidence of dedicated test suites verifying each adapter works correctly with the full stubbing API. This prevents regressions when core matching/stubbing logic changes. New contributors can add spec files that test each adapter independently.

  • [ ] Create spec/http_lib_adapters/ directory structure mirroring lib/webmock/http_lib_adapters/
  • [ ] Add spec/http_lib_adapters/net_http_adapter_spec.rb testing stub_request, request expectations, and body/header matching for Net::HTTP
  • [ ] Repeat for http_rb_adapter, excon_adapter, typhoeus_hydra_adapter, and other critical adapters
  • [ ] Run specs in CI.yml only when optional adapter gems are available (using conditional gemfile groups)

Add missing unit tests for request matching matchers in lib/webmock/matchers/

The matchers directory contains 4 matcher files (HashArgumentMatcher, HashIncludingMatcher, HashExcludingMatcher, AnyArgMatcher) for sophisticated request matching, but these are likely only tested indirectly through integration tests. Direct unit tests would improve maintainability and make matcher behavior explicit for contributors.

  • [ ] Create spec/matchers/hash_including_matcher_spec.rb with tests for basic inclusion, nested hash matching, and edge cases
  • [ ] Create spec/matchers/hash_excluding_matcher_spec.rb testing exclusion logic and interactions with HashIncludingMatcher
  • [ ] Create spec/matchers/any_arg_matcher_spec.rb verifying it matches all input types
  • [ ] Add tests verifying matchers work correctly in RequestPattern (lib/webmock/request_pattern.rb)

Add missing specs for request body diff functionality and error reporting

lib/webmock/request_body_diff.rb and lib/webmock/request_signature_snippet.rb exist for generating helpful failure messages when expectations fail, but lack dedicated test coverage. This directly impacts user experience when tests fail. New tests would validate that diff output is clear and accurate.

  • [ ] Create spec/request_body_diff_spec.rb testing diff generation for JSON, XML, form-encoded, and plain text bodies
  • [ ] Add tests for lib/webmock/request_signature_snippet.rb verifying it generates readable snippets for failed requests
  • [ ] Add tests for edge cases: nil bodies, binary data, very large bodies, and mismatched content types
  • [ ] Verify stub_request_snippet.rb (lib/webmock/stub_request_snippet.rb) generates valid Ruby code that can be copied into tests

🌿Good first issues

  • Add comprehensive tests for lib/webmock/matchers/hash_excluding_matcher.rb and hash_including_matcher.rb—these are matcher utilities with likely incomplete test coverage for edge cases like nested hashes and non-string keys.
  • Document the adapter pattern and add inline comments to lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb explaining how to add a new HTTP library—currently no README section walks new contributors through adding support for an unsupported library.
  • Create integration test for lib/webmock/request_body_diff.rb—this error message helper shows diffs of mismatched request bodies but likely lacks tests covering binary payloads, large bodies, and encoding mismatches.

Top contributors

Click to expand
  • @koic — 34 commits
  • @bblimke — 26 commits
  • @misdoro — 15 commits
  • @c960657 — 6 commits
  • [@Christoph Rieß](https://github.com/Christoph Rieß) — 2 commits

📝Recent commits

Click to expand
  • ce700d9 — Version 3.26.2 (koic)
  • ddf8a43 — Merge pull request #1121 from criess/cr/curb-http-2-parse-headers (koic)
  • 035e9fc — [fix] add support to parse http/2 request on curb adapter (Christoph Rieß)
  • 29d3532 — Merge pull request #1123 from sferik/support-http_rb-6 (koic)
  • 801ad3b — Merge pull request #1122 from criess/cr/curb-easy-code-as-alias (koic)
  • a4de224 — Add HTTP.rb 6.0.0 compatibility to http_rb adapter (sferik)
  • c6cf2f1 — [fix] CurbAdapter alias code from response_code (Christoph Rieß)
  • 596d8a8 — Merge pull request #1113 from koic/ci_against_ruby_4_0 (koic)
  • 86977f8 — Run CI against Ruby 4.0 (koic)
  • cc11b78 — Merge pull request #1114 from koic/remove_pride_option_from_minitest_rake_task (koic)

🔒Security observations

WebMock is a testing library with generally sound security practices. The primary security concerns are: (1) lack of provided dependency information preventing vulnerability scanning, (2) potential XXE and JSON bomb vulnerabilities in parsing components, (3) URI and HTTP header validation risks, and (4) the attack surface introduced by supporting multiple HTTP client adapters. The library is designed for testing/stubbing only, which limits real-world risk. No hardcoded credentials, obvious injection flaws, or infrastructure misconfiguration issues were detected from the file structure. Recommend implementing automated dependency scanning, input validation hardening in parsing/URI/header handling, and regular security audits of adapter implementations.

  • Medium · Missing Dependency Security Information — Gemfile / Gemfile.lock (not provided). No dependency file (Gemfile.lock or similar) was provided for analysis. Without locked dependency versions, it's impossible to verify if any gems have known security vulnerabilities. The project uses multiple HTTP client adapters that could have outdated versions. Fix: Always commit Gemfile.lock to version control. Regularly run 'bundle audit' or 'bundler-audit' to check for known vulnerabilities in dependencies. Use tools like Dependabot or Snyk to automate vulnerability scanning.
  • Low · Potential XML External Entity (XXE) Vulnerability — lib/webmock/util/parsers/xml.rb. The codebase includes XML parsing functionality (lib/webmock/util/parsers/xml.rb). Without reviewing the actual parser implementation, there's a risk of XXE attacks if XML parsing is not properly configured to disable external entities. Fix: Review the XML parser implementation to ensure XXE protection is enabled. Disable DTD processing and external entity resolution in the XML parser configuration.
  • Low · JSON Parsing Without Validation — lib/webmock/util/parsers/json.rb. The codebase includes JSON parsing functionality (lib/webmock/util/parsers/json.rb). If the JSON parser is not properly validating input, it could be vulnerable to JSON bomb attacks or other malicious payloads. Fix: Ensure JSON parsing uses safe parsing methods with appropriate size limits. Validate parsed JSON structure before processing. Consider implementing request payload size limits.
  • Low · URI Parsing Security — lib/webmock/util/uri.rb. The codebase handles URI parsing (lib/webmock/util/uri.rb). Improper URI parsing could lead to SSRF (Server-Side Request Forgery) vulnerabilities if not properly validated, especially given the stubbing nature of the library. Fix: Validate and sanitize all URIs before processing. Implement URI scheme whitelisting if applicable. Test for SSRF vectors in URI handling.
  • Low · HTTP Header Injection Risk — lib/webmock/util/headers.rb and all HTTP adapter files. The library handles HTTP headers extensively (lib/webmock/util/headers.rb). If headers are not properly validated, they could be subject to header injection attacks (CRLF injection). Fix: Validate all headers to prevent CRLF (\r\n) injection. Sanitize header values and keys before processing. Use established HTTP libraries that handle this properly.
  • Low · Multiple HTTP Client Adapters - Attack Surface — lib/webmock/http_lib_adapters/. The codebase supports numerous HTTP client libraries (net_http, httpclient, curb, typhoeus, excon, etc.). Each adapter introduces potential security risks if not properly maintained or if underlying libraries have vulnerabilities. Fix: Regularly update all supported HTTP client libraries. Document minimum supported versions. Conduct security audits on adapter implementations. Monitor security advisories for all supported libraries.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.