Lagom Message Broker API Testing

Many of us have been working with Lagom, so I will skip telling about Lagom. Let’s just quickly go through the  important APIs that Lagom provides:

  • Service API
  • Message Broker API
  • Pesistence API

In this blog, we will see how we can test the Message Broker API provided by Lagom. But before doing that let’s just briefly see what this API provides!

Lagom’s Message Broker API lets services communicate with each other asynchronously by providing a distributed publish-subscribe model that services can use to share data via topics.
And as we all know the importance to write test cases for whatever code we write, so to be able to do so Lagom also provides ways to test this message broker Api.

Lagom lets de-coupled services to be tested by providing in-memory implementations of the Message Broker API to run tests fast, instead of starting the broker for consumption and publishing of messages in test cases.

Enough of the talking, lets see some code!

Here is an upstream service named HelloService which is responsible for the production of messages to the topic named greetings

And there is also a consumer service named StreamService which is consuming from greetings topic of HelloService.

There are two ways in which we can consume the messages.
First one is to consume the messages in the StreamServiceImpl itself, and the second one by creating the consumer class and binding it as an EagerSingleton in the module.
It depends on your use case which one to go with.

Here we will be binding the consumer class as an EagerSingleton class as we want to pull messages continuously from greetings topic of HelloService.

import akka.Done;
import akka.stream.javadsl.Flow;
import org.knoldus.hello.api.HelloEvent;
import org.knoldus.hello.api.HelloService;

import javax.inject.Inject;
import java.util.concurrent.CompletableFuture;

/**
 * This subscribes to the HelloService event stream.
 */
public class StreamSubscriber {

  @Inject
  public StreamSubscriber(HelloService helloService, StreamRepository repository) {
    // Create a subscriber
    helloService.helloEvents().subscribe()
      // And subscribe to it with at least once processing semantics.
      .atLeastOnce(
        //consume events and do some processing
      );

  }
}

So, we have two services, one is the HelloService whose responsibility is to produce messages  to the topic and second one is the StreamService which consumes from HelloService. Testing both in isolation is very important.

Let’s first see how we can test the consumer class.
For testing the consumer implementation in isolation with the producer, we require to start the Service under test i.e. StreamService along with a stub of the upstream Service which is responsible for producing data into the topic in our case “HelloService“, to verify if the messages are consumed properly from the topic or not, the steps  to be followed are:

I. Setting up the server:
i. Create a server with a modified Setup where the upstream HelloService is replaced with a HelloServiceStub.

final ServiceTest.Setup setup = defaultSetup().withCassandra(true).configureBuilder(builder -> builder.overrides(
        bind(HelloService.class).to(HelloServiceStub.class)
));

ii. Get the service client for a service.

HelloService service = testServer.client(HelloService.class);

II. Stubbing the upstream service
i. 
An instance of a ProducerStub is to be declared. This instance will be bound when the Server is started and the HelloServiceStub created.

private static ProducerStub<HelloEvent> producer;

ii. Inject ProducerStubFactory to obtain a ProducerStub for the appropriate Topic in the constructor.

iii. Request the producer for a specific topic: The stubbed method that implements the TopicCall, must return the Topic bound to the ProducerStub created in the constructor.

III. In the test case:
Use the ProducerStub to send messages to the topic and interact normally with the service under test to verify the Service code.
Here is the whole test class with the server setup and stub of the upstream service along with the test cases:

We have seen how we can test the consumer, let’s see how we can test the producer in isolation from the consumer. Following are the steps to be followed:

Setting up the server
i.
Using the ServiceTest, create a client representing the producer service.
ii. Use the created client to subscribe to the published topic.
iii. Finally, after interacting with the Service to cause the emission of some events you can assert events were published on the Topic.

I hope you have understood the topic well. If you have any doubts, please leave a message in the comments section below.
Thank you for reading. Happy blogging 🙂
References:

  • https://www.lagomframework.com/documentation/current/java/MessageBrokerTesting.html#Message-Broker-Testing

Written by 

I am a Software Consultant and has experience of more than 1.5 years. I like to study and write about latest technologies.

Leave a Reply

Knoldus Pune Careers - Hiring Freshers

Get a head start on your career at Knoldus. Join us!