When writing an integration test for a Spring Boot application (Service A) that uses a RestTemplate (and Ribbon under the hood) and Eureka to resolve a Service B dependency, I get a "No instances available" exception when calling the Service A.
I try to mock the Service B away via WireMock, but I don't even get to the WireMock server. It seems like the RestTemplate tries to fetch the Service instance from Eureka, which doesn't run in my test. It is disabled via properties.
Service A calls Service B. Service discovery is done via RestTemplate, Ribbon and Eureka.
Does anyone have a working example that includes Spring, Eureka and WireMock?
I faced the same problem yesterday and for the sake of completeness here is my solution:
This is my "live" configuration under src/main/java/.../config
:
//the regular configuration not active with test profile
@Configuration
@Profile("!test")
public class WebConfig {
@LoadBalanced
@Bean
RestTemplate restTemplate() {
//you can use your regular rest template here.
//This one adds a X-TRACE-ID header from the MDC to the call.
return TraceableRestTemplate.create();
}
}
I added this configuration to the test folder src/main/test/java/.../config
:
//the test configuration
@Configuration
@Profile("test")
public class WebConfig {
@Bean
RestTemplate restTemplate() {
return TraceableRestTemplate.create();
}
}
In the test case, I activated profile test
:
//...
@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ServerCallTest {
@Autowired
private IBusiness biz;
@Autowired
private RestTemplate restTemplate;
private ClientHttpRequestFactory originalClientHttpRequestFactory;
@Before
public void setUp() {
originalClientHttpRequestFactory = restTemplate.getRequestFactory();
}
@After
public void tearDown() {
restTemplate.setRequestFactory(originalClientHttpRequestFactory);
}
@Test
public void fetchAllEntries() throws BookListException {
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
mockServer
.andExpect(method(HttpMethod.GET))
.andExpect(header("Accept", "application/json"))
.andExpect(requestTo(endsWith("/list/entries/")))
.andRespond(withSuccess("your-payload-here", MediaType.APPLICATION_JSON));
MyData data = biz.getData();
//do your asserts
}
}