Technology
January 14, 2026

Open-sourcing RMQ RPC MockServer: faster component tests for RabbitMQ RPC systems

Alexander Demin
Fellow Engineer
Explore Career Opportunities
Navigate the future with confidence.

Step into a high-growth global firm where continuous development, values and impact lead the way.

Explore unique insights and untapped expert knowledge for the world’s top business professionals

Here at Dialectica, a tech-powered information services firm, we invest heavily in development productivity and engineering excellence, so we can deliver value to our clients and internal teams quickly, safely, and with high confidence.

We already have solid unit testing and a healthy end-to-end suite. But in a service-oriented architecture, unit tests alone can’t validate the real behavior of a service as a black box. And end-to-end tests often require large parts of the system to be running, which is slow, fragile, and (honestly) expensive in terms of developer focus.

That’s where component testing shines. They allow to run a single service “for real”, but mock all of its external dependencies in a generic and repeatable way. This shortens the feedback loop and pushes confidence earlier in the lifecycle - classic shift-left testing.

What was the catch? Most off-the-shelf mock servers focus on HTTP. Our ecosystem heavily relies on RabbitMQ RPC (request-reply over AMQP), and we couldn’t find a tool that met our needs - small, fast, flexible… and that just works.

So we built one, battle-tested it across many services in our workflows, and now we’re open-sourcing it.

Meet RMQ RPC MockServer - a mock server for RabbitMQ RPC applications. 

https://github.com/dialecticanet-com/rmq-rpc-mockserver

What RMQ RPC MockServer does

RMQ RPC MockServer lets you:

  • Subscribe to one or more RabbitMQ queues (bound to exchanges and routing keys your service sends RPCs to)
  • Define expectations for incoming RPC requests (exchange, routing key, and body matcher)
  • Return predefined responses when a request matches
  • Inspect assertion history to see exactly what matched (and what didn’t)

It’s a “dependency simulator” for RabbitMQ RPC - purpose-built for component tests and local development.

Key features

Dual API: gRPC and HTTP (same capabilities)

You can manage the server via:

  • gRPC API (strongly typed, fast)
  • HTTP JSON API generated via internal gRPC-Gateway (simple curl/Postman usage)

Both interfaces expose the same operations and stay consistent by design.

Flexible matching: exact JSON, partial JSON, or regex

When you create an expectation, you can choose one of these match strategies:

  • Exact JSON match is great for strict contracts - the request body must match exactly (field order doesn’t matter).
  • Partial JSON match is great for real systems - match only the important fields and ignore things like generated UUIDs or timestamps.
  • Regex match is useful when the payload isn’t JSON or you want flexible matching on raw text.

These match strategies are first-class in the API and can be easily extended to cover more specific use-cases.

Priority ordering

When multiple expectations could match the same request, you can set a priority (integer value). Higher value always wins. If two expectations have equal priority, earlier-created wins. This makes it easy to implement “specific override” expectations on top of broader defaults.

Lifetime controls: TTL and match-count limits

Expectations can expire in two ways:

  • TTL - automatically expires after N seconds
  • Usage limit - valid for N matches (or unlimited)

This is extremely handy in tests. It allows you to define “this dependency must be called exactly once” and you’ll catch accidental retries or duplicate calls.

Assertions tracking + real-time logging

MockServer records all received requests and whether they matched an expectation, so debugging test failures becomes much more straightforward. And it logs details that help you understand what has happened when something doesn’t match.

Dynamic queue subscriptions

You can subscribe/unsubscribe from queues at runtime via the API without any mockserver restarts.

Quick start (Docker + curl)

1) Run the MockServer

docker run -p 8080:8080 -p 8081:8081 \
  -e RABBITMQ_URL=amqp://guest:guest@localhost:5672 \
  ghcr.io/dialecticanet-com/rmq-rpc-mockserver:latest

If your RabbitMQ is running on the host, you may need --network host or host.docker.internal.

2) Subscribe to the target queue

curl -X POST http://localhost:8080/api/v1/subscriptions \
  -H "Content-Type: application/json" \
  -d '{"queue":"my-service-queue","idempotent":true}'

Important: the queue must already exist in RabbitMQ. MockServer does not create it.

3) Create an expectation (partial JSON match in the example)

curl -X POST http://localhost:8080/api/v1/expectations \
  -H "Content-Type: application/json" \
  -d '{
    "request": {
      "exchange": "my_exchange",
      "routing_key": "my.routing.key",
      "json_body": {
        "body": {"action":"create","userId":123},
        "match_type": "MATCH_TYPE_PARTIAL"
      }
    },
    "response": {
      "body": {"status":"success","userId":123}
    },
    "times": {"remaining_times": 1},
    "priority": 10
  }'

This expectation matches once, then expires - perfect for component tests.

4) Verify what happened with assertions

curl "http://localhost:8080/api/v1/assertions?status=matched"

You can also query unmatched requests or filter by expectation id.

How it fits into component tests

Imagine a service under test that calls two dependencies via RabbitMQ RPC:

In a component test, you:

  1. Start the service under test (real container/process)
  2. Start RabbitMQ (real broker, often dockerized)
  3. Start RMQ RPC MockServer and subscribe it to the RPC queues your service calls
  4. For each dependency call you expect, create an expectation:
    • match on exchange + routing key
    • match payload (partial or exact JSONl)
    • limit to exactly one match if the service should not retry
  5. Run the test scenario and assert on:
    • the service output (HTTP/gRPC/RMQ response, DB state, emitted messages…)
    • and optionally MockServer assertion history (“did we call dependency X correctly?”)

This pattern gets you most of the realism of end-to-end tests, while keeping setup and debugging dramatically simpler.

Debugging unmatched requests (where the tool saves time)

When something doesn’t match, you don’t want to guess.

MockServer keeps assertion history for both matched and unmatched requests, including the candidate request details (exchange, routing key, body) and optionally the expectation data. That makes failures actionable: you can see exactly what your service sent, and why it didn’t match your expectation.

For test isolation, there are also reset endpoints that clear expectations and subscriptions.

Contribution

If you want to contribute, the repo includes a clear development workflow, plus instructions for proto generation if you extend the API.

https://github.com/dialecticanet-com/rmq-rpc-mockserver

We’d love:

  • bug reports and feature requests
  • real-world examples from different languages and frameworks
  • PRs (with tests!) that improve matching, dev experience, or documentation

If your team is doing RabbitMQ RPC at scale, we hope this tool helps you move faster with more confidence.

Receive insights and updates – straight to your inbox.
Let’s stay connected
Subscribe
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Alexander Demin
Fellow Engineer