Spring Integration Testing – WireMock and MQ

When writing integration tests for parts of the application that talk to other applications, for example calling REST APIs or sending JMS messages, sometimes we just want to test the application and not do end to end test. In this case, we would need to mock these other applications or their behavior.

Mocking REST

For mocking the rest calls in the tests, we can use WireMock extension. Here is an example of how to do it with Junit5.

First we need to add dependencies for WireMock extension, here I am using Maven

  <!-- Wiremock dep -->
        <dependency>
            <groupId>com.github.jenspiegsa</groupId>
            <artifactId>wiremock-extension</artifactId>
            <version>0.4.0</version>
        </dependency>

And we need repository as well:

   <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>

Now, to the test:

  1. Annotate test class with WireMock Extension
@ExtendWith(WireMockExtension.class)
@SpringBootTest
public class SampleTestIT {

2. Create local test configuration for WireMock server (In this example, it runs on port 8081):

    @TestConfiguration
    public static class RestTemplateBuilderProvider {

        @Bean(destroyMethod = "stop")
        public WireMockServer wireMockServer() {
            WireMockServer wireMockServer = with(wireMockConfig().port(8081));
            wireMockServer.start();
            return wireMockServer;
        }

    }

and autowire it in the test class

    @Autowired
    WireMockServer wireMockServer;

Now, to mock a call to some path, in the test function, you can use something like this:

  CustomDto customDto = CustomDto.builder()
                .id(UUID.randomUUID())
                .upc("1234")
                .build();

        wireMockServer.stubFor(
                get(CustomServiceRestTemplate.SOME_PATH_HERE + "1234")
                .willReturn(okJson(objectMapper.writeValueAsString(customDto)))
        );

Mocking MQ

To mock ActiveMQ server, you can simply add the dependency with scope test. With Spring Boot, when it sees the dependencies on classpath, it will auto configure the MQ server. Important to note here is that we are not actually using a mock server, but an actual in memory server. We mock services listening and responding to queues.

       <!-- JMS Artemis, test scope -->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>artemis-jms-server</artifactId>
            <scope>test</scope>
        </dependency>

Now, to mock the services listening and replying to queues, you’d have to create a test component, for example:

@Slf4j
@RequiredArgsConstructor
@Component
public class ExampleMQListener {

    private final JmsTemplate jmsTemplate;

    @JmsListener(destination = JmsConfig.QUEUE_EXAMPLE_REQUEST)
    public void listen(Message message) {

        ExampleRequest exampleRequest = (ExampleRequest) message.getPayload();

        jmsTemplate.convertAndSend(JmsConfig.QUEUE_EXAMPLE_RESULT,
                ExampleResult.builder()
                .isValid(true)
                .requestId(exampleRequest.getId())
                .build()
                );
    }
}