Update: Link to repo is moved to answer because repo is now updated with code from answer below.
Problem description
Current code is working, but it is using gcloud beta emulators pubsub from google/cloud-sdk for integration tests.
- Integration tests are slow due to the size of the google/cloud-sdk image
- pubsub emulator has to run on a fixed port, there seems to be no way to tell Micronaut which port the emulator is running on
I'll need to set the following environment variable in maven-surefire-plugin
.
<environmentVariables>
<PUBSUB_EMULATOR_HOST>localhost:8085</PUBSUB_EMULATOR_HOST>
</environmentVariables>
How this can be done in Spring Boot
According to Test Containers | Gcloud Module, the correct way of implementing integration tests with PubSubEmulatorContainer in Spring Boot is like this: https://github.com/saturnism/testcontainers-gcloud-examples/blob/main/springboot/pubsub-example/src/test/java/com/example/springboot/pubsub/PubSubIntegrationTests.java
This will bring up the container on a random port, and that is possible because of DynamicPropertyRegistry
in Spring. It seems that Micronaut is missing this possibility.
Doc: https://www.testcontainers.org/modules/gcloud/
I'm looking for a working example of a JUnit5 or Spock integration test implemented in Micronaut 3.x that is using PubSubEmulatorContainer
like described in the above doc.
Related doc: https://micronaut-projects.github.io/micronaut-gcp/latest/guide/#emulator
There are some comments on GitHub around configuring TransportChannelProvider
. I'm able to inject an instance and inspect it, but I still haven't found out exactly what to do.
These are the closest leads so far: https://github.com/micronaut-projects/micronaut-gcp/issues/257 https://github.com/micronaut-projects/micronaut-gcp/pull/259
Update 2023-07-23 Bumped to Micronaut 4.0.1, refactored away Lombok in Java-demo. Link: pubsub-emulator-demo repo
Update 2023-05-01 Updated pubsub-emulator-demo repo with Kotlin/Kotest-example.
TL;DR
We'll need to start the testcontainer first, get emulator host address and then call
ApplicationContext.run
like this:Small Github repo with example code: https://github.com/roar-skinderviken/pubsub-emulator-demo
Long answer with code
I finally managed to make a working solution using Micronaut 3.0.2 and Spock. A related Micronaut PR got me on track, together with this article: Micronaut Testing Best Practices https://objectcomputing.com/files/9815/9259/7089/slide_deck_Micronaut_Testing_Best_Practices_webinar.pdf
First a PubSubEmulator class (Groovy)
Then a fixture for PubSubEmulator (Groovy)
Then a specification class (Groovy) that starts the container, creates a topic and a subscription.
The clue here is to pass in
pubsub.emulator.host
as part of the configuration when callingApplicationContext.run
.Remaining part of the code is very similar to the Spring Boot example I linked to in my question.
Then a factory class (Groovy) for mocking credentials
And finally, a Spock test spec.