Testing Your HiveMQ Extension

To write automated tests for your extension, you can use the official HiveMQ Testcontainers Module or the HiveMQ Testcontainer.

These libraries can automatically create HiveMQ Docker containers and deploy your extension inside.

Test Your HiveMQ Extension with Gradle

Use the HiveMQ Extension Gradle Plugin and the HiveMQ Testcontainers Module to test your extension.

Packaging extensions with the HiveMQ Gradle Plugin

The HiveMQ Extension Gradle Plugin adds an integrationTest task which executes tests from the integrationTest source set.

Integration test source files are defined in src/integrationTest.

Integration test dependencies are defined via the integrationTestImplementation, integrationTestRuntimeOnly, etc. configurations.

The integrationTest task builds the extension first and unzips it to the build/hivemq-extension-test directory. The tests can then load the built extension into a HiveMQ container.

Add these dependencies to your build.gradle.kts:

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")

    integrationTestImplementation("com.hivemq:hivemq-mqtt-client:1.3.0")
    integrationTestImplementation("org.testcontainers:junit-jupiter:1.17.1")
    integrationTestImplementation("org.testcontainers:hivemq:1.17.1")
}

In this example, the extension modifies all 'PUBLISH' to contain the string 'modified'. To test the HiveMQ extension, do the following:

  1. Create a new HiveMQContainer

  2. Register the HiveMQContainer with JUnit 5

  3. Use the unzipped extension that was created into the build/hivemq-extension-test directory and added to the classpath by the integrationTest task

  4. Connect your MQTT clients to the HiveMQ instance that is running inside the container. Use the port and the hostname that you retrieve from the container with the getMqttPort() and getHost() methods.

  5. Assert the expected behavior.

@Testcontainers
public class TestMqttIT {

    @Container (2)
    public final @NotNull HiveMQContainer container = (1)
        new HiveMQContainer(DockerImageName.parse("hivemq/hivemq-ce:latest"))
            .withExtension(MountableFile.forClasspathResource("<id-of-your-extension>")); (3)

    @Test
    void test_mqtt() throws InterruptedException {
        final Mqtt5BlockingClient publisher = Mqtt5Client.builder()
            .serverPort(container.getMqttPort()) (4)
            .identifier("publisher")
            .buildBlocking();

        publisher.connect();

        final Mqtt5BlockingClient subscriber = Mqtt5Client.builder()
            .serverPort(container.getMqttPort()) (4)
            .serverHost(container.getHost()) (4)
            .identifier("subscriber")
            .buildBlocking();

        subscriber.connect();

        subscriber.subscribeWith().topicFilter("topic/test").send();

        publisher.publishWith()
            .topic("topic/test")
            .payload("Hello World!".getBytes()).send();

        final Mqtt5Publish receive = subscriber.publishes(MqttGlobalPublishFilter.ALL).receive();

        assertNotNull(receive); (5)
        assertEquals("modified", new String(receive.getPayloadAsBytes())); (5)
    }
}

Test Your HiveMQ Extension with Maven

Use the HiveMQ Maven Plugin and the HiveMQ Testcontainer to test your extension.

Packaging extensions with the HiveMQ Testcontainer (Maven)

The HiveMQ Testcontainer is able to automatically build extensions that use Maven by invoking the package task. All dependencies and resources are included. You only need to provide the location of the extension’s pom.xml in the constructor of the MavenHiveMQExtensionSupplier. MavenHiveMQExtensionSupplier.direct() returns a MavenHiveMQExtensionSupplier that targets the current project.

Add these dependencies to your pom.xml:

<dependency>
    <groupId>com.hivemq</groupId>
    <artifactId>hivemq-testcontainer-junit5</artifactId>
    <version>2.0.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.8.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.8.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.hivemq</groupId>
    <artifactId>hivemq-mqtt-client</artifactId>
    <version>1.3.0</version>
    <scope>test</scope>
</dependency>

In this example, the extension modifies all 'PUBLISH' to contain the string 'modified'. To test the HiveMQ extension, do the following:

  1. Create a new HiveMQTestContainerExtension

  2. Register the Extensions with JUnit 5

  3. Use MavenHiveMQExtensionSupplier.direct() to add the HiveMQ extension to the HiveMQTestContainerRule.

  4. Connect your MQTT clients to the HiveMQ instance that is running inside the container. Use the port and the hostname that you retrieve from the container with the getMqttPort() and getHost() methods.

  5. Assert the expected behavior.

public class TestMqttIT {

    @RegisterExtension (2)
    public final @NotNull HiveMQTestContainerExtension container = (1)
        new HiveMQTestContainerExtension()
            .withExtension(MavenHiveMQExtensionSupplier.direct().get()); (3)

    @Test
    void test_mqtt() throws InterruptedException {
        final Mqtt5BlockingClient publisher = Mqtt5Client.builder()
            .serverPort(container.getMqttPort()) (4)
            .identifier("publisher")
            .buildBlocking();

        publisher.connect();

        final Mqtt5BlockingClient subscriber = Mqtt5Client.builder()
            .serverPort(container.getMqttPort()) (4)
            .serverHost(container.getHost()) (4)
            .identifier("subscriber")
            .buildBlocking();

        subscriber.connect();

        subscriber.subscribeWith().topicFilter("topic/test").send();

        publisher.publishWith()
            .topic("topic/test")
            .payload("Hello World!".getBytes()).send();

        final Mqtt5Publish receive = subscriber.publishes(MqttGlobalPublishFilter.ALL).receive();

        assertNotNull(receive); (5)
        assertEquals("modified", new String(receive.getPayloadAsBytes())); (5)
    }
}

Debug with HiveMQ Testcontainer

You can debug the extension in the same way as described in Debug IntelliJ and Debug Eclipse. Simply set the port binding for the debug port:

@Rule
public final @NotNull HiveMQContainer container = new HiveMQContainer(DockerImageName.parse("hivemq/hivemq-ce:latest"))
        .withDebugging();