Long-lived mock services drift more quietly than most teams expect.

When that happens, a green build can stop meaning what everyone thinks it means.

If your team keeps ReadyAPI virtual services in git, those files are part of the contract surface now. That is where the trouble starts.

Most teams already watch application code and OpenAPI changes closely. Mock services usually get less attention. They begin as useful scaffolding, then quietly become long-lived project assets.

A field gets renamed. A response code changes. The contract moves forward.

The ReadyAPI virtual service does not.

CI still passes because CI is talking to the old version of reality.

That is not a flaky-test problem. It is a false-confidence problem.

A small mismatch is enough

You do not need a dramatic API break to get bad test signal.

Take a simple case. The contract now says:

amount:
  type: integer

But the stored ReadyAPI response still returns:

{ "amount": "99" }

That kind of drift is easy to miss in code review. The route still exists. The field still exists. The test still gets a value back.

But the mock is no longer a good stand-in for production.

That is enough to make a green build less trustworthy than it looks.

Why this happens

ReadyAPI is not really the problem. Long-lived mocks are.

Once a virtual service is committed to the repo, it needs the same maintenance pressure as code, schemas, and migrations. In practice, a lot of teams do not give it that pressure.

They update the OpenAPI file but not the stored response body. They fix the real endpoint but not the mock that QA or the frontend still depends on.

The result is predictable:

By the time somebody notices, the failure often shows up in the wrong place. It looks like an application bug, a test bug, or a strange environment issue when the real problem is that the mock has drifted.

What I wanted from a check

I did not want a generic contract-testing platform pitch, and I did not want to solve this with a prompt every time.

I wanted a narrow check that reads the ReadyAPI REST files already in the repo, compares them with the contract the team says it supports, and points to the exact place drift starts.

That means checking things like:

That is the job MockDoctor tries to do.

It reads ReadyAPI REST project XML files or extracted service directories, loads either an OpenAPI document or a JSON contract, normalizes both sides to the same METHOD + path model, and compares the pieces that actually matter for drift.

What the output should look like

One checked-in fixture in the MockDoctor repo intentionally returns a string for amount where the contract requires an integer.

The comparison output looks like this:

GET /api/orders/{id} | service=OrdersService
- [response-body-schema-mismatch] ReadyAPI response for GET /api/orders/{id} does not match the contract schema.
$.amount: must be integer

That is enough context to act on. You get the operation, the failure category, and the exact JSON path that failed validation.

The same run can also write an HTML report when you want to hand the result to somebody outside the terminal.

Why this should be a tool, not a prompt

You can paste a mock response and an OpenAPI snippet into ChatGPT and ask whether they differ. That is useful for one-off investigation.

It is not the same as a repeatable repository check.

Once a task needs to be stable, boring, and safe to run in CI, I want a tool. I want the same input to produce the same result every time. I want stable failure categories, machine-readable output, and a non-zero exit code when the drift is real.

This is one of those jobs.

Current scope

MockDoctor is intentionally small in v0.1.0.

It supports:

It does not try to cover SOAP, dispatch-script execution, or full runtime virtualization behavior.

That narrower scope is deliberate. A smaller tool that does one neglected job well is more useful than a broader one that promises everything and blurs the actual use case.

Try it with the checked-in example

npm install
npm run build
node ./dist/cli.js compare --config ./examples/openapi/mockdoctor.config.json

If you want to force a real drift case and generate an HTML report:

node ./dist/cli.js compare \
  --readyapi ./test/fixtures/readyapi/orders-project-schema-drift.xml \
  --openapi ./test/fixtures/contracts/orders-openapi.yaml \
  --html-report ./artifacts/mockdoctor-drift.html

Repo:

github.com/kumarsourav12/MockDoctor

Project site:

kumarsourav12.github.io/MockDoctor