假设我创建了一个 RestTemplate Bean,如下所示:
@Bean
@LoadBalanced //Not working with tests
public RestTemplate restTemplate(RestTemplateResponseErrorHandler handler){
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(handler);
restTemplate.setInterceptors(Collections.singletonList(
new MyClientHttpRequestInterceptor())
);
return restTemplate;
}
在控制器中,我使用它来调用外部服务。为了编写测试,我使用 MockWebServer 来模拟外部调用:
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = RestApiTestingApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class HttpBinControllerIT {
public static MockWebServer mockBackEnd;
@Autowired
private MockMvc mvc;
@BeforeAll
static void setUp() throws IOException {
mockBackEnd = new MockWebServer();
mockBackEnd.start();
}
@DynamicPropertySource
static void registerPgProperties(DynamicPropertyRegistry registry) {
registry.add("my.service.url",
() -> String.format("http://localhost:%s", mockBackEnd.getPort()));
}
@AfterAll
static void tearDown() throws IOException {
mockBackEnd.shutdown();
}
@Test
public void restTemplateGet_200() throws Exception {
final Dispatcher dispatcher = new Dispatcher() {
@Override
public MockResponse dispatch(RecordedRequest request) {
switch (request.getPath()) {
case "/get":
if(!request.getHeader("foo").isEmpty() &&
request.getHeader("foo").equalsIgnoreCase("fooValue"))
return new MockResponse().setResponseCode(200).setBody("test");
}
return new MockResponse().setResponseCode(404);
}
mockBackEnd.setDispatcher(dispatcher);
mvc.perform(get("/bin/rest/get")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(result -> {
result.equals("test");
});
}
}
我在测试中得到以下异常:
2021-06-20 04:30:51.344 WARN 86739 --- [oundedElastic-1] o.s.c.l.core.RoundRobinLoadBalancer : No servers available for service: localhost
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No instances available for localhost
如果我注释掉@LoadBalanced
,所有测试都有效。
如何在测试中禁用负载平衡?
注意- 虽然可能有另一种方法来测试或创建 resttempalte bean 测试。这只是一个示例。实际上,我没有创造它的自由。它来自一个自定义 jar,该 jar 具有自定义配置的 rest-template。
示例项目在这里。