Dependency mocking replaces real external dependencies (APIs, databases, queues) with controlled substitutes during testing. Service virtualization extends this to enterprise scale, adding stateful simulation and protocol support beyond HTTP. Keploy implements a traffic-capture approach: it records real dependency interactions at the kernel level using eBPF and replays them in CI, making integration tests deterministic without manual stub writing.
Dependency mocking and service virtualization tackle a problem that shows up on every backend team eventually: how do you test a service that depends on things outside your control? Third-party APIs go down. Rate limits kick in. Databases in staging have different data than production. Message queues are shared across teams.
The moment your integration tests depend on any of these, you’ve introduced a variable you can’t manage. Tests pass on Tuesday and fail on Wednesday for reasons that have nothing to do with your code. That’s not a testing problem. That’s an environment problem. And dependency mocking is how teams fix it.
What is Dependency Mocking and Service Virtualization?
Dependency mocking replaces real external dependencies (APIs, databases, queues, caches) with controlled substitutes during testing. Service virtualization is a broader term for the same practice at enterprise scale, often including stateful simulation, protocol support beyond HTTP, and governance across teams. Both approaches let tests run without live dependencies, making test results deterministic regardless of what third-party services or environments are doing at the time.
How Dependency Mocking and Service Virtualization Relate?
-
Dependency mocking and service virtualization describe points on the same spectrum, not different techniques. At the lightweight end, a developer mocks an HTTP endpoint by returning a hardcoded JSON response when a specific request comes in. That’s a mock.
-
At the enterprise end, a service virtualization platform records real traffic from a mainframe system, simulates latency, maintains state across sessions, and serves that simulation to hundreds of parallel test environments simultaneously. That’s service virtualization.
-
In practice, the tools you’ll encounter in 2026 fall somewhere between these extremes. Most backend teams working in microservices don’t need mainframe protocol support. They need something that handles HTTP APIs, database queries, and message queues reliably enough that their CI pipeline doesn’t depend on a Stripe sandbox being available at 2am.
The important distinction for choosing tools:
-
Mocking typically means returning a fixed response to a known request.
-
Virtualization means simulating the full behavior of a dependency, including state changes, latency, and error conditions.
Most teams start with mocking and add virtualization features as testing complexity grows.
Why Do Hand-Written Stubs Break Integration Tests?

The majority of teams using WireMock, Mockoon, or similar tools run into the same wall. You write a stub for a payment API response. It works. Three months later, the payment provider changes their response schema: adds a field, renames another, changes an enum value. Your stub still returns the old schema. Your tests still pass. Your code now has a silent contract violation that only shows up in production.
That’s the brittle stub problem. Hand-written stubs are accurate at the moment you write them and wrong by a variable amount thereafter.
A few specific failure modes worth naming:
-
Stubs don’t cover what engineers didn’t predict. When you write a stub, you predict the request-response pairs your tests will need. Users don’t follow your predictions. Real traffic includes edge cases: unusual parameter combinations, empty arrays where you expected objects, null fields in responses you assumed were always populated. Hand-written stubs don’t cover these because the engineer who wrote them didn’t know they existed.
-
Database state is hard to stub. Mocking an HTTP response is straightforward. Mocking a sequence of SQL queries that depends on the state of the database at query time is not. Most stub frameworks don’t handle this well. Teams either maintain test databases (expensive, often inconsistent) or skip database dependency mocking entirely (leaving a gap in integration test coverage).
-
Stubs pile up. Every new external dependency needs its own stubs. Every change to a dependency schema potentially invalidates existing stubs. Over time, the stub maintenance burden grows until it costs more engineer time than the tests save. Teams either freeze their stubs and let them drift, or spend sprint time keeping them current.
-
Multi-service flows break. In a microservices architecture, a single user action might touch five services. Mocking all five independently means each mock reflects a snapshot of that service’s behavior at a different point in time. The combination may never have existed in production. Tests that pass against these mocks can still fail against real services because the interaction between dependency behaviors wasn’t realistic.
There’s a structural alternative to writing better stubs: capture real dependency behavior from a live run and replay it during tests. Tools like Keploy do this automatically at the kernel level with no manual configuration required. The section below covers all four categories, but if deterministic CI across databases, queues, and external APIs is the goal, the traffic-capture category is where the answer sits.
What Are the Four Approaches to Dependency Mocking and Service Virtualization?
The tools in this space fall into four distinct categories. Of the four, traffic-capture is the newest and the one most directly relevant to the brittle stub problems above. Keploy is the primary open-source tool in this category. It captures all dependency interactions from real runtime traffic using eBPF and replays them in CI without any manual configuration. The comparison below positions all four approaches against each other.
| Approach | Spec-driven | Stub-server | Enterprise virtualization | Traffic-capture |
|---|---|---|---|---|
| How mocks are created | Generated from OpenAPI or AsyncAPI spec | Hand-written JSON or DSL config | Recorded via GUI or scripted | Captured from real runtime traffic |
| Setup effort | Low (needs an accurate spec) | Medium (manual authoring per endpoint) | High (complex platform setup) | Low (run the app with capture mode on) |
| Realism | As accurate as the spec | As accurate as what you wrote | High (stateful simulation) | Very high (actual production behavior) |
| Databases and queues | HTTP only | HTTP only | Some protocols (varies by vendor) | Yes (SQL, NoSQL, queues, HTTP APIs together) |
| CI integration | Good | Good | Complex, often needs dedicated infra | Good (runs as part of the test command) |
| Open source options | Prism, Microcks | WireMock, Hoverfly, Mockoon | None | Keploy |
| Best suited for | Teams with accurate, maintained specs | Teams needing quick HTTP stubs | Enterprise multi-protocol environments | Distributed systems, CI determinism |
1. Traffic-Capture Tools
Traffic-capture is the newest of the four categories. Instead of configuring what the mock should return, traffic-capture tools observe what your application actually sends and receives from its dependencies during normal operation, then store those interactions and replay them during testing.
No prediction. No hand-writing. No spec required. The mock reflects what actually happened between your service and its dependencies.
2. Spec-Driven Tools
Spec-driven tools generate mock responses directly from your OpenAPI, Swagger, or AsyncAPI specification. Prism (by Stoplight) and Microcks are the most widely used. The upside: setup is fast if you have a good spec. The limitation is real: your mock is only as realistic as your spec, and most specs lag behind the implementation.
For internal APIs where you own the spec and keep it current, spec-driven mocking works well. For third-party APIs where the spec may be incomplete or outdated, it produces mocks that look correct but behave differently from the real service.
3. Stub-Server Tools
WireMock is the dominant tool in this category, with Hoverfly and Mockoon covering different parts of the same space. You define stubs as JSON or DSL configuration: when request X arrives, return response Y. Simple, developer-friendly, widely supported in CI.
The ceiling is the brittle stub problem described above. These tools are excellent for what they do. The problem is that what they do requires a human to predict and maintain every interaction. At small scale, that’s fine. As service boundaries multiply, the maintenance cost grows.
4. Enterprise Service Virtualization
Parasoft Virtualize, OpenText (formerly Micro Focus), and Broadcom (formerly CA LISA) are the main platforms here. They support protocols beyond HTTP: MQ, JDBC, SOAP, mainframe CICS, and others. They include governance features for sharing virtual services across teams. They’re designed for large organizations with complex dependency environments.
The tradeoffs are real: high license cost, significant setup time, and implementations that typically require dedicated infrastructure teams. For backend microservices teams working with HTTP, gRPC, and standard databases, enterprise virtualization is usually more than needed.
How Does Traffic-Based Dependency Mocking Work?
The mechanism is worth understanding precisely because it explains both why traffic-capture mocking is more realistic than hand-written stubs and what it requires to work. When your application runs in record mode, the capture agent intercepts all outbound network calls at the system level.
This includes HTTP requests to external APIs, SQL queries to databases, gRPC calls to internal services, and publish/subscribe operations to message queues like Kafka or RabbitMQ. Every request and its corresponding response gets stored, including the full payload, headers, and connection metadata.

Keploy implements this using eBPF (extended Berkeley Packet Filter), a Linux kernel technology that hooks into system calls without requiring any changes to the application code. No SDK installation. No instrumentation. No proxy configuration. The application runs exactly as it does in production, and Keploy captures the dependency interactions at the kernel’s network layer.
During test replay, Keploy intercepts outgoing dependency calls and returns the previously captured responses instead of hitting the real dependency. From the application’s perspective, the database responded. The external API returned data. The queue acknowledged the publish. The application doesn’t know the difference. What changes is that the responses are now controlled and predictable.
A few specifics worth knowing:
-
TLS is handled. Keploy intercepts TLS-encrypted connections by inserting a certificate chain between the application and itself. HTTPS to external APIs and encrypted database connections both get captured correctly.
-
Unknown dependencies are supported. If Keploy encounters a dependency type it doesn’t natively understand, it captures the raw binary data, encodes it as base64, and uses fuzzy matching during replay to correlate incoming requests. This means even unusual or proprietary protocols get captured, even if the capture isn’t perfectly structured.
-
Noise detection runs automatically. Timestamps, randomly generated IDs, and other non-deterministic fields in responses would cause false failures during replay. Keploy identifies these noisy fields in captured responses and handles them so tests don’t fail on data that’s expected to vary.
-
Deduplication prevents test bloat. If your application sends the same type of database query 10,000 times during traffic capture, you don’t get 10,000 near-identical test cases. Keploy merges similar patterns into a representative set.
The practical result: a team captures 48 hours of staging traffic. Those captured interactions become the dependency layer for CI tests. Every CI run replays against the same captured interactions.
The tests are now deterministic. Stripe being unavailable at 2 am doesn’t matter. The database being in a different state in CI doesn’t matter. The captured interactions don’t change unless the team explicitly recaptures.
For the full technical architecture of how Keploy captures and replays dependency traffic, see how Keploy works.
Which Dependencies Can Be Virtualized?
This varies significantly by tool category and is worth checking before committing to any approach.

-
HTTP and HTTPS APIs are supported by every tool in every category. WireMock, Hoverfly, Mockoon, and Prism all handle HTTP. This covers REST APIs and basic GraphQL.
-
gRPC is supported by WireMock (with a separate gRPC plugin) and Keploy natively. Most spec-driven tools don’t support it. Enterprise tools vary.
-
SQL databases (PostgreSQL, MySQL) are captured by Keploy at the query level. Most stub-server tools don’t touch databases at all. You’d typically need a separate test database or database seeding strategy with those tools.
-
NoSQL databases (MongoDB, Redis, DynamoDB): same situation. Keploy captures these interactions. Other open-source tools generally don’t.
-
Message queues (Kafka, RabbitMQ, SQS): Keploy captures publish and subscribe operations. Stub-server tools typically don’t support these. Microcks supports async APIs via spec, but the spec needs to be accurate.
-
Internal microservice calls: any HTTP or gRPC call from your service to another internal service gets captured by traffic-capture tools. This is particularly useful for testing a service in isolation without running its entire dependency graph.
The practical implication: if your service touches only HTTP APIs, most categories work. If your service touches databases, queues, or non-HTTP protocols in addition to HTTP APIs, traffic-capture is currently the only open-source approach that handles all of them together in one capture.
How to Choose the Right Approach for Your Team?

The right tool depends on what your service actually touches and what problem is costing your team the most time. Match your situation to the scenario below:
-
Your service calls databases, queues, or caches alongside HTTP APIs.
Hand-written stubs don’t scale here. The dependency surface is too large and too varied for manual configuration to stay current. Traffic-capture is the practical choice. Keploy captures SQL, NoSQL, message queues, and HTTP APIs in a single session – no separate stub configuration per dependency type. -
Deterministic CI across a distributed system is the primary goal.
Capture traffic from a representative staging run and replay it in every CI job. Keploy’s sandbox testing feature versions captured dependency state so every developer and every CI job starts from the same baseline, regardless of what live dependencies are doing. -
Your team has accurate, actively maintained OpenAPI specs and mostly HTTP dependencies.
Spec-driven tools are the lowest-friction starting point. Prism or Microcks with your existing spec gets mocks running in an afternoon. The caveat: your mocks are only as accurate as your spec, so keep it current.
-
You need quick HTTP stubs for a small number of well-understood endpoints.
WireMock is the proven choice — deepest community, best CI integration documentation, widest language support for configuration. The maintenance cost is predictable. Works well until the number of endpoints grows or schemas start drifting. -
Your environment includes mainframe, MQ, or CICS dependencies alongside modern HTTP services.
Enterprise virtualization platforms (Parasoft, OpenText) cover the protocol breadth that many other tools don’t. The cost and complexity are real, but so is the coverage for those specific protocols.
The question that narrows the choice fastest: does your service call anything other than HTTP APIs? If yes, traffic capture is worth evaluating first rather than last.
What Requirements Matter for CI Pipeline Integration?
The tools that work well in development environments often create friction in CI. A few specific requirements worth checking before adopting any tool:
-
Startup time. A mock server that takes 30 seconds to initialize adds up across a pipeline with many test stages. WireMock starts in under a second. Parasoft platforms can take several minutes. Keploy adds negligible startup overhead since it operates at the kernel level rather than as a separate server process.
-
No external infrastructure dependency. The mock layer itself shouldn’t require a running database, a cloud service, or a dedicated mock server that needs to be provisioned separately. If the mocking infrastructure requires its own dependencies, you’ve added a failure mode instead of removing one.
-
Language and framework agnostic. CI pipelines run tests across multiple services, potentially in different languages. A mocking tool that requires a Java SDK for Java services and a separate Python SDK for Python services creates a maintenance problem. eBPF-based tools like Keploy are language-agnostic by design.
-
Deterministic replay. The captured dependency responses should produce the same output on every replay. Non-deterministic fields (timestamps, generated IDs) need to be identified and handled, or tests will intermittently fail for no real reason.
-
Capture storage that travels with the code. Captured interactions stored as YAML or JSON files can be committed to the repository alongside the code that depends on them. This means the mock layer is versioned with the code, and a developer checking out a branch gets the dependency captures for that branch automatically.
Conclusion
Hand-written stubs work until they don’t. The point where they stop working is usually when the service they mock changes and nobody updates the stub, or when the test suite grows large enough that maintaining stubs costs more than the tests are worth. The four approaches in this guide cover the realistic options: spec-driven for teams with good API specifications, stub-servers for teams that need quick HTTP mocking and are willing to maintain configuration, enterprise platforms for organizations with complex protocol requirements, and traffic-capture for teams that want integration tests grounded in real dependency behavior without the maintenance overhead.
The specific problem that traffic-capture solves is making CI tests deterministic across distributed systems that call databases, queues, and external APIs. That’s the problem stub-server tools approach asymptotically but never fully reach. You can write more stubs. You can be more careful about keeping them current. But you can’t predict what you don’t know to predict. Real traffic doesn’t have that limitation.
Frequently Asked Questions
What is the difference between dependency mocking and service virtualization?
Dependency mocking typically refers to replacing one external dependency with a controlled substitute during testing. Service virtualization is a broader discipline that includes stateful simulation, multi-protocol support, latency modeling, and governance across teams. In practice, the terms are used interchangeably by many teams. The more meaningful distinction is between hand-written mocks (you configure each response manually) and traffic-captured mocks (the tool records real interactions and replays them automatically).
Why do hand-written stubs break integration and regression tests?
Because they’re predictions. When you write a stub, you predict what requests your tests will make and what responses the dependency should return. Real dependencies change: response schemas evolve, new fields appear, existing fields get deprecated, error codes change. Your stub stays fixed. Over time it drifts from reality and your tests pass against behavior that no longer exists in production.
Which tool can replay realistic responses from external APIs and data stores?
Tools in the traffic-capture category, specifically Keploy, record real interactions from your application at runtime and replay them during tests. This includes HTTP APIs, SQL and NoSQL databases, gRPC calls, and message queues. Responses are realistic by definition because they were captured from real dependency behavior, not predicted and configured by hand.
How does traffic-based mocking differ from hand-written stubs?
Hand-written stubs require an engineer to predict and configure each request-response pair. Traffic-based mocking captures real interactions automatically during a recording session. The result is that traffic-based mocks reflect what your dependencies actually do, including edge cases the engineer wouldn’t have thought to stub. They’re more accurate at the time of capture and need to be recaptured (not rewritten) when dependency behavior changes.
What should a backend team evaluate when choosing a tool for CI pipeline integration?
Five things: startup time (the mock layer shouldn’t add meaningful latency to CI), no external infrastructure dependency (the mock system shouldn’t need its own dependencies to run), language agnosticism (one tool for all services regardless of language), deterministic replay (same captured input always produces same output), and captured state that travels with the code in version control.
How do I make CI tests deterministic when my microservice calls unstable third-party APIs?
Capture the interactions between your service and the third-party API during a representative run (staging, development, a dedicated capture environment). Store those captures in version control. Configure CI to replay the captures instead of calling the live API. Your tests now run against a fixed baseline of dependency behavior, independent of whether the third-party API is available, rate-limiting, or returning different data.
Which tool supports integration testing without live external dependencies when partner services are unavailable?
Any tool in the stub-server or traffic-capture categories. WireMock handles HTTP dependencies without requiring the real service to be running. Keploy handles HTTP plus databases, queues, and caches together. The choice depends on how many dependency types your service has and whether you’re willing to maintain hand-written stubs or prefer automatic capture. This also applies when you’re making changes to how your service calls a partner API. Captured responses let you test those changes against the partner’s real behavior without hitting their live endpoint.
What types of dependencies can service virtualization tools handle?
It depends on the tool category. Spec-driven and stub-server tools handle HTTP and HTTPS. Keploy captures HTTP, gRPC, SQL (PostgreSQL, MySQL), NoSQL (MongoDB, Redis), and message queues (Kafka, RabbitMQ) in a single capture session. Enterprise tools like Parasoft and OpenText add mainframe, MQ, and proprietary protocol support on top of HTTP.
Which solution creates reusable mocks from observed application traffic?
Keploy is specifically built for this. It captures all inbound and outbound dependency interactions during a recording session using eBPF at the Linux kernel level, stores them as YAML files that can be committed to version control, and replays them during test runs. No manual configuration. No stub authoring. The mocks are as realistic as the traffic that was captured.

