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://github.com/specmatic/specmatic/releases

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/znsio/specmatic-order-bff-nodejs
Download Specmatic: https://github.com/znsio/specmatic/releases

Available in the Pro plan or higher

Related Posts

Specmatic vs WireMock

By Hari Krishnan

Comparison: Specmatic vs WireMock

API mocking is only effective if the mocks are truly representative of the provider / services they are emulating. Deviations between mocks and providers can
Read More
Specmatic vs Pact & Pactflow comparison

By Hari Krishnan

Comparison: Specmatic vs Pact.io and Pactflow.io

Specmatic and Contract Driven Development differ significantly from Pact. We built Specmatic out of our own necessity where Pact did not fit the bill for
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 Sample projects with OpenAPI https://docs.specmatic.io/sample_projects.html#openapi
Read More
Contract Testing with Specmatic - Markus Oberlehner

Stubbing an HTTP end-point with Specmatic

Markus Oberlehner gives a brief overview on the topic of Contract Testing with Specmatic and his experience using it for stubbing an HTTP end-point.
Read More

By Joel Rosario

TMForum ODA CTK API specification conformance testing with Specmatic

We recently discovered some major issues with the TMForum Conformance Test Kit (CTK) v5.0.0 and will demonstrate how using Specmatic can address these problems.
Read More
Specmatic API Coverage Report

Early detection of mismatches between your API specs and implementation: Exploring Specmatic’s API Coverage Report

Specmatic’s API coverage report helps identify any mismatches between an OpenAPI specification and an application's endpoints early in the development lifecycle. The report lists all
Read More
Dave Farley pointing to the Specmatic tool for easy microservice testing, featured on Dave Farley's Continuous Delivery channel.

“Easy Microservice Testing” – Specmatic featured on Continuous Delivery channel

Dave Farley is a respected author and widely recognised proponent of Continuous Delivery. In this video on his Continuous Delivery YouTube channel he discusses why
Read More
JDBC stubbing with Redis and Specmatic contract testing.

Break the Chains of Database Dependencies: Leveraging Specmatic for JDBC Stubbing

With Specmatic JDBC stub, you can easily test APIs without the need for a complex database setup. By switching out the real database with a
Read More

JMS Mocking with AsyncAPI using Specmatic

The JMS mock is wire compatible and can be controlled entirely from within the test. This means you can run the test locally or also
Read More
Redis stubing - specmatic contact development with contract testing.

Redis Stubbing with Specmatic Contract Testing

Instead of using an actual instance of Redis, we'll stub it out and have the contract test set expectations so that the Redis stub knows
Read More