Open Source Service Virtualization Tools I’ve Actually Used (and When Each One Made Sense)

Open Source Service Virtualization Tools I’ve Actually Used (and When Each One Made Sense)

# opensource# virtualization# webdev# devops
Open Source Service Virtualization Tools I’ve Actually Used (and When Each One Made Sense)Marx Jenes

Open Source Service Virtualization Tools I've Actually Used (and When Each One Made...

Open Source Service Virtualization Tools I've Actually Used (and When Each One Made Sense)

The first time I heard the phrase "service virtualization," I assumed it was some enterprise thing with a sales team attached. Turns out I'd been doing a scrappy version of it for years, mostly by hand-rolling fake endpoints in Express whenever a partner API was down, rate-limited or just painfully slow.

Over the last few years I've worked on a payments integration, a couple of microservice-heavy backends and one very stubborn legacy system. Along the way I've tried most of the open source service virtualization tools people usually recommend. Some stuck. A couple I dropped after a week. None of them is "the best one," which I know is an annoying thing to read in a roundup, but it's true. They solve different problems.

So instead of ranking them, I'll walk through the ones I've actually used, what each is like day to day, and the situations where it earned its place.

First, What I Mean by Service Virtualization

Quick definitions, because people use these words loosely. A mock or stub usually lives inside your test code and fakes one function or one call. Service virtualization is a bit bigger. You stand up something that behaves like a whole dependency (a third-party API, a database, a downstream microservice) and your app talks to it over the network the same way it would talk to the real thing.

Why bother? In my experience it's usually because the real service charges per call, or it's flaky, or it doesn't exist yet because another team is still building it. Any of those can stall a test suite for days. Virtualizing the dependency gets you unstuck.

What I Look For Before Picking One

Before getting into specific tools, here's what I've learned to check up front. It saves a lot of switching later.

Protocol support comes first. If everything you call is plain HTTP and JSON, almost any tool works. Throw in gRPC, Kafka or raw TCP and the list gets short fast.

Then there's how the fake behavior gets created. Some tools want every stub written by hand, others record real traffic and play it back. Hand-written stubs give you precise control. Recorded ones save time and tend to match reality more closely. I've wanted both at different points, honestly.

I also think about who'll maintain the stubs. A tool the whole team can read and update beats a clever one only I understand. And does it slot into CI without drama? If it needs a special VM or a ten-step setup, it won't survive on a busy team.

The Open Source Service Virtualization Tools I've Actually Used

Same format for each one: how it works, when it made sense for me, and a few things worth knowing before you start.

Keploy: Record-and-Replay From Real Traffic

How it works: Keploy records real API calls to your application, along with the calls your app makes to its own dependencies like databases and external APIs, and turns them into test cases and mocks. It uses eBPF to capture traffic, so there's no need to change application code or wrap your HTTP clients. On replay, it serves the recorded dependency responses as mocks and compares your app's output with what it recorded.

When it made sense: One of those microservice backends had decent unit tests and almost no integration coverage, and nobody had time to write hundreds of stubs. Recording a few days of staging traffic gave us a regression suite that matched how the service was really used, database calls included. That database part mattered more than I expected. Most tools here virtualize HTTP services, and this covered the Postgres side as well.

Good to know: It captures traffic at the kernel level, so it runs natively on Linux, and on macOS or Windows you'd run it through Docker or WSL. Recording works best when realistic traffic flows through the app first. A staging environment or a few scripted user flows is plenty to get started.

WireMock: Flexible HTTP Stubbing

How it works: WireMock started life as a Java library, and these days it also runs as a standalone server or a Docker container. You describe stubs as JSON mappings, basically "match this request, return that response." Request matching covers URLs, headers and bodies. It can record from a real API and save what it sees as stubs, and it can simulate faults like slow responses or dropped connections.

When it made sense: Our payments integration. The provider's sandbox went down at least once a week, usually right before a demo. We recorded the main flows into WireMock once, cleaned the stubs up by hand, and after that our integration tests stopped caring whether the sandbox was alive. Fault simulation turned out to be a nice bonus. We finally tested what happens when the provider takes eight seconds to answer, which, yes, happened in production more than once.

Good to know: It's at its best with REST and JSON. On a big API the mapping files pile up quickly, so agree on a folder structure early. Ask me how I know.

Hoverfly: Lightweight Proxy-Based Simulation

How it works: Hoverfly is written in Go and runs as a small proxy between your app and the services it calls. You put it in capture mode, run traffic through it, then switch to simulate mode and it replays what it saw. There are other modes too, like spy, which passes through anything it doesn't have a recording for. It comes with a CLI called hoverctl for managing everything.

When it made sense: A Go service that talked to four internal APIs owned by four different teams. Getting all four into one test environment at the same time was close to impossible. With the proxy approach we didn't have to change how the service made its calls at all. Point it at Hoverfly, record once, done.

Good to know: Since it works as a proxy, HTTPS means the client has to trust Hoverfly's certificate, which cost one of our devs most of an afternoon. It's centered on HTTP and HTTPS, so other protocols are out of scope.

Mountebank: Multi-Protocol Test Doubles

How it works: Mountebank runs on Node.js and uses what it calls imposters. Each imposter listens on a port and pretends to be a service. You create them through its REST API, and HTTP, HTTPS, TCP and SMTP are supported out of the box. It can proxy to a real service to record responses, and you can inject JavaScript when canned responses aren't enough.

When it made sense: That legacy system I mentioned. Part of it spoke a custom protocol over raw TCP, which ruled out most HTTP-only tools straight away. Mountebank's TCP imposters let us fake that piece well enough to test the newer services around it.

Good to know: The configuration style takes a little getting used to. And injection is powerful enough that it's easy to write test logic nobody else wants to debug, so I kept ours as small as I could.

Microcks: Mocks Straight From API Specs

How it works: Microcks takes your API artifacts (OpenAPI files, AsyncAPI specs, gRPC protobufs, GraphQL schemas, even Postman collections) and turns the examples inside them into live mock endpoints. It can also run contract conformance tests against your real implementation. It's built with Kubernetes in mind, though you can run it locally with Docker Compose.

When it made sense: A newer microservices project where the team was already spec-first. The OpenAPI files existed before the code did, so mocks generated from them let frontend and backend work in parallel from day one. It handled our Kafka event mocks too, which was a big plus.

Good to know: It's a bigger piece of infrastructure than a single mock server, so it pays off most when you have lots of APIs and specs to manage. Your mocks are only as good as the examples in your specs. Thin examples, thin mocks.

So Which One, When?

If you skipped straight to this part, no judgment. Here's roughly how I'd decide now.

Want regression tests and mocks generated from real usage, database calls included, without writing stubs by hand? Keploy. Mostly REST, and you want precise control over every response? WireMock. Can't touch the app's code and just need to capture and replay HTTP traffic? Hoverfly's proxy model is hard to beat. Stuck with TCP or SMTP alongside HTTP? Mountebank. Spec-first team with lots of APIs and event streams? Microcks.

Plenty of teams end up running two of these side by side, by the way. We had WireMock and Microcks together for a while and it was fine.

My Take After All of This

The tool matters less than people think. What matters more is picking one dependency that's genuinely hurting you and virtualizing that first. Teams that try to fake their entire architecture in week one usually give up by week three. I did, once.

So find the flakiest or most expensive service your tests lean on, try one of these against it for a sprint, and see whether your test runs get calmer. That'll tell you more than any roundup, this one included.