When you run more than one controller instance, your server will not start because of port clash right? How were you able to run multiple controller tests simultaneously?

In any Spring Boot project, running multiple controller instances simultaneously in tests does not necessarily cause a port clash. This is because, in most cases, unit tests for controllers are typically run without needing to start a real web server or bind to an actual port. Spring Boot provides several tools and strategies to run controller tests in isolation, avoiding port clashes.

❓ How Multiple Controller Tests Run Simultaneously:

  1. Mocking Web Layer with @WebMvcTest:
  2. What it is: Spring Boot provides the @WebMvcTest annotation to focus only on testing the web layer (i.e., controllers). When you use this annotation, Spring Boot doesn’t start the full application context or a real web server. Instead, it mocks the web layer and allows you to test individual controllers in isolation.
  3. Why it works: Since no real server is started, there is no need for a real port, and thus no port clashes. You are essentially testing the controller’s functionality without having to bind it to a network port.
  4. Example:

```java

@WebMvcTest(MyController.class)

public class MyControllerTest {

 @Autowired
 private MockMvc mockMvc;
@Test  

public void testController() throws Exception {

mockMvc.perform(get(“/api/endpoint”))

.andExpect(status().isOk());

}

}

 - **MockMvc:** The`MockMvc\` object simulates HTTP requests and allows testing the controller logic without starting an actual web server.
5. **Using `@SpringBootTest` with Mocking:**
6. **What it is:** When you need to load the full application context, including multiple components and controllers, you can use `@SpringBootTest`. By default, `@SpringBootTest` can start a real web environment (which would require a port). However, you can configure it to avoid using an actual port by setting it to a **mock environment**.
7. **How to configure it:** You can set `@SpringBootTest(webEnvironment = WebEnvironment.MOCK)` to run the tests in a mock environment without binding to any real port.
8. **Example:**  

```java

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)

public class QEatsControllerTest {

@Autowired
private MockMvc mockMvc;
@Test

public void testMultipleControllers() throws Exception {

mockMvc.perform(get(“/eats/endpoint1”))

.andExpect(status().isOk());

 mockMvc.perform(get("/eats/endpoint2"))
         .andExpect(status().isOk());

}


}  

```
9. In-memory Servers for Integration Testing:
10. What it is: In cases where you want to run an actual server for integration testing but avoid port clashes, you can configure tests to use random ports. Spring Boot provides an option to run the server on a random port so that each test instance gets its own port, preventing port conflicts.
11. How to configure it: Use @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) to assign a random port to each test instance.
12. Example:

```java

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

public class RandomPortIntegrationTest {

@LocalServerPort
private int port;
@Autowired

private TestRestTemplate restTemplate;

@Test

public void testRandomPortServer() throws Exception {

String baseUrl = “http://localhost:” + port + “/api/endpoint”;

ResponseEntity response = restTemplate.getForEntity(baseUrl, String.class);

assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);

}


}  

```

- Random port: Each test runs on a random port, so no port clashes occur even if multiple instances of the server run concurrently.
13. Using @MockBean to Avoid Actual Service Calls:
14. What it is: In addition to testing controllers, you often need to mock the dependencies they use, such as services or repositories. Spring Boot’s @MockBean annotation allows you to mock beans so that your controller tests don’t depend on actual service or database interactions.
15. Example:

```java

@WebMvcTest(MyController.class)

public class MyControllerTest {

@Autowired
private MockMvc mockMvc;
@MockBean

private MyService myService;

@Test

public void testControllerWithMockService() throws Exception {

when(myService.getData()).thenReturn(new DataResponse());

 mockMvc.perform(get("/api/endpoint"))
         .andExpect(status().isOk());

}

```

}

```

Summary:

In Spring Boot applications, you can run multiple controller tests without port clashes by using various techniques:

  • @WebMvcTest: Tests only the controller layer, without starting a real server or requiring a port.
  • @SpringBootTest with WebEnvironment.MOCK: Starts the full Spring context but without an actual web server, avoiding port clashes.
  • @SpringBootTest with WebEnvironment.RANDOM_PORT: Starts the server on a random port, ensuring no conflicts when running multiple instances.
  • MockMvc and @MockBean: Simulate HTTP requests and mock dependencies without needing a running server.

Using these techniques, you can effectively test multiple controllers simultaneously without any issues related to port conflicts.