Spring Boot中WireMockServer Stub的JUnit测试无法运行求助
WireMock测试无输出、无法运行的排查与解决
以下是针对你的测试无响应、无报错问题的常见排查方向和解决方法:
1. 检查JUnit注解版本匹配
代码中使用的@Before、@After、@Test是JUnit 4的注解,如果项目依赖的是JUnit 5(Jupiter),会导致测试完全不执行。
- 确认依赖:如果用JUnit 4,确保引入
junit:junit依赖,注解导入org.junit.Before、org.junit.Test;如果用JUnit 5,需要替换为@BeforeEach、@AfterEach,并导入org.junit.jupiter.api.Test。
2. 放松WireMock请求体匹配规则
你的Stub使用了equalToJson严格匹配请求体,但RestTemplate序列化TrackMetadata时,字段顺序、格式可能和你写的JSON不一致,导致请求未命中Stub,RestTemplate一直等待响应,看起来像没运行。
- 改用宽松匹配:
equalToJson("{\"name\":\"test_name\",\"durationMs\":1000,\"explicit\":true}", true)(第二个参数忽略字段顺序) - 或者用
containingJson替代,只校验关键字段存在 - 临时去掉
withRequestBody匹配,先让请求命中Stub,再逐步添加规则
3. 给RestTemplate配置JSON序列化器
默认RestTemplate可能缺少合适的HttpMessageConverter,导致TrackMetadata无法序列化为JSON,请求卡住但无报错。
给RestTemplate添加Jackson序列化配置:
restTemplate = new RestTemplate(); ObjectMapper objectMapper = new ObjectMapper(); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper); restTemplate.getMessageConverters().add(converter);
4. 排查IDE或构建工具问题
- 用命令行运行测试(比如
mvn test -Dtest=TrackControllerWireMockServerTest),排除IDE配置问题 - 检查IDE的JUnit运行配置,确认选择了正确的测试类,无错误VM参数
5. 验证WireMock启动状态
在setUp中添加日志输出,确认WireMock正常启动:
System.out.println("WireMock server started on port: " + wireMockServer.port());
也可以指定固定端口避免冲突:
wireMockServer = new WireMockServer(WireMockConfiguration.options().port(8089));
修改后的示例代码
import org.junit.Before; import org.junit.After; import org.junit.Test; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import static com.github.tomakehurst.wiremock.client.WireMock.*; public class TrackControllerWireMockServerTest { private WireMockServer wireMockServer; private RestTemplate restTemplate; @Before public void setUp() { // 指定固定端口避免冲突 wireMockServer = new WireMockServer(8089); wireMockServer.start(); System.out.println("WireMock running on port: " + wireMockServer.port()); configureFor("localhost", wireMockServer.port()); // 宽松匹配请求体,忽略字段顺序 stubFor(post(urlPathEqualTo("/codechallenge/createTrack")) .withQueryParam("isrc", equalTo("TEST_ISRC")) .withRequestBody(equalToJson("{\"name\":\"test_name\",\"durationMs\":1000,\"explicit\":true}", true)) .willReturn(aResponse() .withStatus(HttpStatus.OK.value()) .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) .withBody("{\"isrc\":\"TEST_ISRC\",\"name\":\"test_name\",\"durationMs\":1000,\"explicit\":true}"))); // 配置RestTemplate支持JSON序列化 restTemplate = new RestTemplate(); ObjectMapper objectMapper = new ObjectMapper(); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper); restTemplate.getMessageConverters().add(converter); } @After public void tearDown() { wireMockServer.stop(); } @Test public void testCreateTrack() { TrackMetadata metadata = new TrackMetadata(1000L, "test_name", true); ResponseEntity<Track> responseEntity = restTemplate.postForEntity( "http://localhost:" + wireMockServer.port() + "/codechallenge/createTrack?isrc=TEST_ISRC", metadata, Track.class); assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); assertEquals("TEST_ISRC", responseEntity.getBody().getIsrc()); assertEquals("test_name", responseEntity.getBody().getName()); assertEquals(1000L, (long) responseEntity.getBody().getDurationMs()); assertEquals(true, responseEntity.getBody().isExplicit()); } }
内容的提问来源于stack exchange,提问作者Brendan Ahern
相关产品推荐
相关产品推荐

