WireMock始终意外返回404,求助问题原因
你的测试出现404的核心原因是:RestTemplate没有请求WireMock的端口,而是请求了Spring Boot测试实例的随机端口,所以返回的是Spring应用的404错误响应,而非WireMock配置的Stub结果。
下面是具体问题点和修复步骤:
1. RestTemplate 请求地址错误
你当前的请求代码restTemplate.getForEntity("/some/thing", String.class)没有指定WireMock的地址和端口。由于测试类使用了@SpringBootTest(webEnvironment = RANDOM_PORT),RestTemplate默认会指向Spring Boot测试应用的随机端口,而非WireMock运行的6677端口。
修复:请求时指定WireMock的完整URL:
ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:6677/some/thing", String.class);
2. WireMock 重复启动问题
@BeforeEach会在每个测试方法执行前调用startWireMockServer(),这会导致重复启动WireMockServer,大概率会触发端口占用异常。应该改用@BeforeAll(静态方法)来一次性启动WireMock。
3. @PreDestroy 用法错误
@PreDestroy是Spring用于实例销毁的注解,不能标注在静态方法上,且在JUnit测试中不会生效。应该用@AfterAll静态方法来停止WireMock。
4. 修正后的完整代码
WireMockBase 类
public class WireMockBase { protected static WireMockServer wireMockServer; @BeforeAll public static void startWireMockServer() { // 注意:端口参数用int类型,避免String类型导致的潜在问题 wireMockServer = new WireMockServer(options().port(6677)); wireMockServer.start(); } @AfterAll public static void stopWireMockServer() { if (wireMockServer != null && wireMockServer.isRunning()) { wireMockServer.stop(); } } }
SimpleTest 测试类
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("test") public class SimpleTest extends WireMockBase { // 若Spring容器中已有RestTemplate配置,直接注入;否则手动初始化 private RestTemplate restTemplate = new RestTemplate(); @Test void testGetRequest() throws Exception { wireMockServer.stubFor(get(urlEqualTo("/some/thing")) .willReturn(aResponse() .withHeader("Content-Type", "text/plain") .withBody("Hello world!"))); ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:6677/some/thing", String.class); assertEquals("Hello world!", response.getBody()); } }
额外注意点
你提供的测试结果里Expected和Actual显示顺序异常(预期是404,实际是Hello world),这可能是你写assertEquals时参数顺序搞反了,正确顺序应该是assertEquals(预期值, 实际值)。
内容的提问来源于stack exchange,提问作者Zichen Ma

