MQTT Client testing with junit

Gazouu

I'm trying to test my Spring-Boot application that use a MQTT Client. I want to test several property like these area :

  • Does it handle a connection failure correctly
  • Does it handle a connection success correctly
  • Does it parse the message payload (json?) correctly
  • Does it handle an malformed payload correctly.

(source How do I write tests for an MQTT client?)

So, my MQTT client code is (simplified) :

@Component
public class MQTTController implements MqttCallback {

    MqttClient client;

    @Value("${spring.mqtt.serverURI}")
    private String serverURI;

    @Value("${spring.mqtt.port}")
    private String serverPort;
    
    @Bean
    private MqttClient receiveData() {
        try{
            client = new MqttClient(serverURI + ":" + serverPort, "Receiver");
            client.connect();
            client.setCallback(this);
            client.subscribe("someTopic");
            return client;
        }
        catch(Exception e){
            log.error("MQTT ERROR");
            log.error(e.toString());
        }
        return null;
    }

    public void connectionLost(Throwable cause) {
    }

    public void messageArrived(String topic, MqttMessage message) throws Exception {
        someActionWithTheData(message.ToString());
    }

    public void deliveryComplete(IMqttDeliveryToken token) {
    }
}

The main problem is that during testing, I don't have a MQTT Broker. My broker is only available on a docker container and I must test this class without using it. I searched for some embedded broker for testing inside the mqtt package org.eclipse.paho.client.mqttv3 but I found nothing. And I Don't want to add another dependency to my project just for one unit test.

So, Is there a way to test this class without adding a dependency to a MQTT broker ? If no, what is the lightest way to do it ?

victor gallet

A best practice is to divide the code part of the infrastructure from the business code. In that way, you could write unit tests to only test the business of your application. In your example, you could simply write a unit test to test the method messageArrived. For example,

@Test
public void test_on_message() {

    MQTTController controller = new MQTTController();

    MqttMessage message = new MqttMessage();

    controller.messageArrived("my_topic", message);

    ...
}

You could also use Mockito to provide a mock of MqttMessage and its method ToString.

Then, you could also write integration tests by providing an embedded broker in your tests. I think the best way to do it is to use Testcontainers. You can create a broker MQTT from a docker image. In this example, it creates a Mosquitto broker from it official docker image.

@ClassRule
public static GenericContainer mosquitto = new GenericContainer("eclipse-mosquitto:1.4.12")
    .withExposedPorts(1883, 9001);

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related