#Parallel tests with Spring / Junit + Mock server + Simple Discovery Client
1 messages · Page 1 of 1 (latest)
Ill just paste it here for you
OPs original question
I have a service written in Spring with Eureka which have a lot of tests so I'm trying to run the tests in parallel.
Assuming non-parallel tests, I use mockserver-spring-test-listener-no-dependencies. I also configure my Simple Eureka client to the host and port of the Mock Server instance:
spring:
cloud:
discovery:
client:
simple:
instances:
service-a:
- host: localhost
port: ${mockServerPort}
And my test class would like something like this:
@MockServerTest
@AutoConfigureMockMvc
@SpringBootTest(classes = Application.class)
public class MyTest {
@Autowired
private MockMvc mockMvc;
private MockServerClient client;
@Test
public void testA() {
// Test
}
@TestB
public void testB() {
// Test
}
}
Now I want to add parallelism, this can be done easily by adding a junit config file with parallelism configuration and placing @Execution(ExecutionMode.CONCURRENT) above my test class.
The problem is my tests can't be run with parallelism the way I wrote my tests because both tests try to create a MockServerClient with the same port. One of the tests will pass, the other will get an error like Exception while binding MockServer to port 49363.
I can try switching to a different test dependency like mockserver-junit-jupiter-no-dependencies which allows me to inject an instance of MockServerClient to each test (which I assume isn't shared), but now I can't inject ${mockServerPort} in my application.yml since this dependency isn't made for Spring.
Does anyone have any idea on what I can do? Maybe I'm tackling this problem in the wrong way? For context, I'm following the docs shown here: https://www.mock-server.com/mock_server/running_mock_server.html#spring_test_exec_listener
it's okay - your question is here now
alrighty
The problem is my tests can't be run with parallelism the way I wrote my tests because both tests try to create a MockServerClient with the same port. One of the tests will pass, the other will get an error like Exception while binding MockServer to port 49363.
The idea is that you'll start the mock server inside your test and use @DynamicPropertySource to dynamically set the port to 0 which in return will bind the server to any available port
Then in each of your tests you'll need to start the mock server yourself
Also see: https://www.baeldung.com/mockserver
but that guide doesn't cover the annotation but it shows how to create a mock server
i see, if i tried setting it in my application-test.yml to 0 then because of the race condition theres a chance theyd both bind go the same port so it'd be better to do it in @DynamicPropertySource?
and to start the mock server for each test then I autowire the discovery client and get the port of the service?
yeah on the right track - let me write some psudoish code, sec
@AutoConfigureMockMvc
@SpringBootTest(classes = Application.class)
class MyTest{
private static ClientAndServer mockServer;
@DynamicPropertySource
static void dynamicProperties(DynamicPropertyRegistry registry) {
mockServer = ClientAndServer.startClientAndServer(0);
registry.add("server.port", () -> mockServer.getLocalPort()); // this might need to the path to your discovery e.g. spring.cloud.discovery.client... port
}
@AfterAll
static void stop() {
mockServer.stop();
}
@Autowired MockMvc mvc;
@Test
void testA() {
// mockServer.when(...), mvc.perform(...)
}
}
sorry bad formatting
no worries i understood it even before you fixed it haha
i still have some questions but i think itd be better for me to try it out and test it for myself before that
thanks for the help!