You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot测试目录放置APP_2模拟控制器及优化测试方案问询

Answers to Your Spring Boot Integration Test Questions

Great questions! Let's break this down step by step to clean up your integration tests and avoid exposing test endpoints in production.

1. Can I Move App_2_Controller to the Test Directory?

Absolutely you can (and should!) move your App_2_Controller to the test directory. This is a best practice because test-specific code has no place in your production source tree—keeping them separate prevents accidental exposure of test endpoints and keeps your main codebase clean.

How to Do It:

  • Create a matching package structure under src/test/java (e.g., if your main controller is in com.yourpackage.controller, create src/test/java/com/yourpackage/controller).
  • Move App_2_Controller.java into this test-side package.
  • Ensure your test class can pick up this controller:
    • If your test uses @SpringBootTest, it will automatically scan packages starting from your main Application class. As long as the test-side controller is in the same (or sub-) package, Spring will detect it when running tests.
    • If the package structure differs, add @Import(App_2_Controller.class) to your HttpRequestTest to explicitly include the test controller.

2. Better Alternatives to Configuration File URL Swaps

Using configuration files to switch URLs works, but there are more flexible, maintainable approaches that avoid cluttering your configs and better isolate tests. Here are two top options:

Option 1: Mock the RestTemplate Directly with @MockBean

Instead of spinning up a real controller to mock APP_2, you can mock the RestTemplate bean that ForwardController uses. This keeps your tests fast and avoids needing a running HTTP endpoint for the mock.

Modify your HttpRequestTest like this:

@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HttpRequestTest {
    @LocalServerPort private int port;
    @Autowired private TestRestTemplate restTemplate;
    
    // Mock the RestTemplate used by ForwardController
    @MockBean private RestTemplate mockRestTemplate;

    @Test
    public void greetingShouldReturnDefaultMessage() throws Exception {
        // Define the mock response for APP_2's /serve endpoint
        ResponseEntity<String> mockApp2Response = new ResponseEntity<>("Hello End of world", HttpStatus.OK);
        
        // Tell Mockito to return this response when exchange() is called with the APP_2 URL
        String app2Url = "app.com:9000/serve"; // Use the real URL here—no config swap needed!
        when(mockRestTemplate.exchange(
                eq(app2Url),
                eq(HttpMethod.GET),
                any(HttpEntity.class),
                eq(String.class)
        )).thenReturn(mockApp2Response);

        // Execute the test
        assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/", String.class))
                .contains("Hello End of world");
    }
}

This way, you don't need the App_2_Controller at all—you're directly mocking the external HTTP call.

Option 2: Use WireMock for Realistic HTTP Mocking

If you want to simulate a real HTTP service (to test request headers, URL parameters, or response handling more accurately), WireMock is the perfect tool. It lets you spin up a temporary HTTP server that mimics APP_2's behavior.

Step 1: Add WireMock Dependency

Add this to your pom.xml (Maven):

<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock-jre8</artifactId>
    <version>2.35.0</version>
    <scope>test</scope>
</dependency>

Step 2: Configure WireMock in Your Test

@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWireMock(port = 9000) // Starts WireMock on port 9000 (matches APP_2's real port)
public class HttpRequestTest {
    @LocalServerPort private int port;
    @Autowired private TestRestTemplate restTemplate;
    @Autowired private Environment environment;

    @Test
    public void greetingShouldReturnDefaultMessage() throws Exception {
        // Define the stub for APP_2's /serve endpoint
        stubFor(get(urlEqualTo("/serve"))
                .willReturn(aResponse()
                        .withBody("Hello End of world")
                        .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)));

        // Verify the test uses WireMock's URL (set via application-test.properties)
        assertThat(environment.getProperty(Constants.APP_2_URL)).isEqualTo("http://localhost:9000/serve");

        // Execute the test
        assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/", String.class))
                .contains("Hello End of world");
    }
}

Now set APP_2_URL=http://localhost:9000/serve in your application-test.properties—no need to touch production configs. WireMock will handle all requests to that URL during tests.

Bonus: If You Still Want to Use a Test Controller

If you prefer keeping the App_2_Controller approach but want to avoid config swaps, use Spring Profiles to enable it only in tests:

  • Add @Profile("test") to App_2_Controller (though moving to test directory is still better):
    @Controller
    @Profile("test")
    public class App_2_Controller {
        // ... existing code ...
    }
    
  • Then set APP_2_URL=http://localhost:${local.server.port}/app2Stub in your test properties to point to the local test controller.

Final Recommendations

  • Always move test-specific controllers to the test directory—it keeps production code clean and avoids accidental exposure.
  • For most cases, @MockBean is the simplest and fastest option if you don't need to test HTTP-level details.
  • Use WireMock when you need to simulate real HTTP interactions (e.g., testing request headers, status codes, or error handling).

内容的提问来源于stack exchange,提问作者shashantrika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:55:55