Kafka Mocking with AsyncAPI using Specmatic

Share this page

Check out the sample code

Sample project: https://github.com/specmatic/specmatic-order-bff-nodejs
Download Specmatic: https://docs.specmatic.io/download

Available in the Pro plan or higher

In our previous post, we looked at how we can stub out Redis with Specmatic so that we can test our application independent of its dependency on Redis. In this post we will be looking at mocking Kafka with Specmatic by leveraging AsyncAPI specification.

Overview – how Specmatic can be used to mock Kafka using AsyncAPI

Let’s take the example of an HTTP consumer that sends a request to an API application. The request is received by the controller, which invokes a service layer that fetches data from an HTTP API dependency, and then drops a message onto a Kafka topic. The service layer returns a response to the controller, which in turn returns a response to the consumer.

To test this application independently, we need to isolate it from its http and Kafka dependencies. Specmatic can stub Http API dependencies by leveraging their OpenAPI specifications. For asynchronous interactions such as those over Kafka, Specmatic can leverage AsyncAPI specifications.

To isolate our application / system under test from its Kafka dependency, let us take an  AsyncAPI specification that defines the format for messages on the Kafka topic and mock it out using Specmatic’s Kafka mock.

asyncapi: 2.6.0
info:
  title: Product audits API
  version: '1.0.0'

servers:
  kafka-dev:
    url: tcp://localhost:61616
    protocol: kafka
channels:
  product-queries:
    publish:
      operationId: publishObjectMessage
      message:
        bindings:
          kafka:
            key:
              type: string
            bindingVersion: '0.4.0'
        payload:
          $ref: "#/components/messages/product"
components:
  messages:
    product:
      name: product
      title: An inventory product
      summary: Product representing items in inventory
      contentType: application/json
      payload:
        type: object
        properties:
          name:
            description: Every product has a name
            type: string
          inventory:
            description: Count of items in inventory
            type: integer
          id:
            description: Unique indentifier of the product
            type: integer
          categories:
            description: A list of product categories
            type: array
            items:
              $ref: "#/components/schemas/category"
  schemas:
    category:
      type: object
      properties:
        id:
           description: The id of the category
           type: integer
        name:
          description: The name of the category
          type: string

YAML

Let’s say we also use Specmatic to run contract tests against the application. First, we must set expectations on  the Kafka mock about messages that it will receive. Then we must set expectations (response mappings) on Specmatic HTTP stub that is leveraging the OpenAPI specification of the HTTP dependency (Domain Service in the diagram above). You can learn more about contract testing and HTTP stubbing with Specmatic in other videos. Finally, Specmatic uses the application’s OpenAPI specification to run contract tests against it.

Each contract test sends a request to the application which is received by the controller which in turn invokes the service layer. The service layer fetches data from the HTTP service stub and drops a message onto the topic on the Kafka mock. The Kafka mock uses an in memory Kafka broker, so the service layer sends messages to it seamlessly. Because of this, to the application it will be exactly like sending messages to a real Kafka broker in production. The service layer responds to the controller, which in turn responds to the contract test. After the contract tests have run, Specmatic asks the Kafka mock to verify the messages that it received. Let’s see this in an actual example.

Code walkthrough: Contract Test demonstrating Specmatic Kafka mock in action

Here’s an application that fetches data from an HTTP API and writes a message to a Kafka broker.

Here is a specmatic.json, in which we provide the path to AsyncAPI specification file for mocking out the Kafka dependency, the OpenAPI specification for stubbing out the HTTP dependency which the application needs, and the OpenAPI specification of the application itself which Specmatic will use to run contract tests.

Now, let’s run the contract tests.

In the API coverage summary for the above test, we have a contract test for one of the APIs, but not for the other, and so it’s marked as missed.

Let’s look at how the Kafka expectations are being set and verified.

After starting the Specmatic Kafka mock, we set an expectation that it would receive a single message on the “product queries” topic. When the test runs, any messages received on this topic are validated against the product queries schema in the AsyncAPI specification. Finally, we verify the kafka mock. This checks if, as per expectations, the mock has received a single message at the product queries topic, and if that message adhered to the AsyncAPI specification. If either of these conditions are not met, or say if a topic that has not been captured in the AsyncAPI specification received a message, the verification fails. The message verification process lets the test keep a tight rein on all Kafka messages sent by the application.

Code walkthrough: API Test demonstrating Specmatic Kafka mock in action

The setup for API tests is on similar lines to the Specmatic contract tests. Let’s take a quick look at the test set up.

Like with the contract tests, we start a Kafka mock, and then we set an expectation that a single message is expected on the product queries topic. Then in the test, we verify that the required message has indeed been received, and this line will verify that only one message on the product queries topic has been received as defined by the expectation set earlier on.

Since the Specmatic Kafka mock is wire compatible and entirely within the control of the test, the test can run locally and in CI and deliver quick feedback early in the cycle. So the application itself runs exactly as it would with a real Kafka.

Sample project: https://github.com/specmatic/specmatic-order-bff-nodejs
Download Specmatic: https://docs.specmatic.io/download

Available in the Pro plan or higher

Related Posts

OpenAPI codegen docgen demo

By Naresh Jain

OpenAPI’s Broken Tooling: Roundtrip Fidelity Failure with CodeGen and DocGen​

Exploring the Strengths and Weaknesses of Automated API Development  Maintaining well-documented and reliable APIs is essential for any microservices development pipelines. At the heart of
Read More
api proxy recording thumb

By Naresh Jain

Replace Live Services with OpenAPI Mocks from Real HTTP Traffic with Specmatic Proxy

API proxy recording: Capture traffic, generate mocks, and simulate faults When you need to test how a system behaves when a downstream API misbehaves, API
Read More
gRPC API resliency test

By Yogesh Nikam

Contract Testing using gRPC Specs as Executable Contracts

Transform your gRPC API specs into executable contracts in seconds Now you can easily leverage your gRPC APIs for contract testing, intelligent service virtualisation and
Read More
kafka+jms

By Hari Krishnan

Contract Testing using AsyncAPI Specs as Executable Contracts

Sample projects with AsyncAPI Sample project with Kafka & AsyncAPI: https://github.com/znsio/specmatic-order-bff-nodejs Sample project with JMS and AsyncAPI: https://github.com/znsio/specmatic-order-bff-jms Sample project with Google Pub/Sub and AsyncAPI: https://github.com/znsio/specmatic-google-pubsub-sample Available in Pro
Read More
Demonstration of the flaws in grpc

By Naresh Jain

gRPC Flaws​ – The Illusion of Safety & Frustrating DevEx in Proto3’s Type-Safe Contracts​

Understanding the Shortcomings of gRPC and How Contract Testing Can Bridge the Gap  In the ever-evolving world of API design, development, and testing, the pursuit
Read More
testing 429 responses thumbnail

By Naresh Jain

When Dependencies Timeout, Does Your API Shed Load with 429 Responses?

When Dependencies Timeout: Engineering Tests that Produce a 429 response Simulating backend slowdowns and verifying that your API returns a proper 429 response is a
Read More

By Naresh Jain

Contract Testing using OpenAPI Specs as Executable Contracts

Demonstration video showing OpenAPI specifications being leveraged as executable contracts with Specmatic
Read More
testing 202 responses thumb

By Naresh Jain

When Downstream Services Lag, Does Your API Gracefully Accept with 202 Responses?

When Downstream Services Lag: Designing Reliable APIs with 202 responses As systems get distributed, synchronous calls to downstream services become fragile. When a downstream service
Read More
mcp auto test exposed mcp servers lying

By Yogesh Nikam

Exposed: MCP Servers Are Lying About Their Schemas

Table of Contents Practical Lessons from MCP Server Testing Over the last few weeks the Specmatic team ran a focused series of MCP server testing
Read More
GraphQL API resiliency testing

API Resiliency and Contract Testing for GraphQL

Transform your GraphQL API specs into executable contracts in seconds Now you can easily leverage your GraphQL APIs for contract testing, intelligent service virtualisation and
Read More