member sound opened SPR-17266 and commented
When sending multiple async requests via RestTemplate using CompletableFuture, and when ignoring any exceptions (eg collecting only the requests that have been successful), the MockRestServiceServer.verify() method will not let the @Test fail!
Example:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class MockRestServiceServerTest {
@Autowired
private MockMvc mvc;
@Autowired
private RestTemplate restTemplate;
private MockRestServiceServer mockServer;
@Before
public void initmock() {
this.mockServer = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
}
@After
public void verify() {
//this should let the test fail, but does not
mockServer.verify();
}
@Test
public void test() throws Exception {
mockServer.expect(once(), requestTo("/remoteurl")).andRespond(withSuccess());
mvc.perform(MockMvcRequestBuilders
.post("/test"))
.andExpect(status().isOk());
}
}
@RestController
public class TestServlet {
@Autowired
private RestTemplate restTemplate;
@PostMapping("/test")
public String test() {
//simulate 3 concurrent requests
List<String> requests = new ArrayList<>();
requests.add("");
requests.add("");
requests.add("");
final AtomicInteger counter = new AtomicInteger(1);
List<CompletableFuture<ResponseEntity<String>>> futures =
requests.stream()
.map(hostReq ->
CompletableFuture.supplyAsync(
() -> {
System.out.println("sending remote request: " + counter.getAndIncrement());
return restTemplate.postForEntity("/remoteurl", null, String.class);
})
.exceptionally(ex -> {
System.out.println("ignoring ex");
return null; //ignoring exceptions
}))
.collect(Collectors.toList());
futures.stream()
.map(CompletableFuture::join)
.filter(Objects::nonNull)
.collect(Collectors.toList());
return "OK";
}
}
The rest template sends 3 requests out, and 2 exceptions are logged (because we set up the mock with once().
So far so good, but the MockRestServiceServer seems not to record the failed requests, and .verify() always passes! But it should fail because 3 requests have been send, instead of the expected one only.
Affects: 5.0.8
member sound opened SPR-17266 and commented
When sending multiple async requests via
RestTemplateusingCompletableFuture, and when ignoring any exceptions (eg collecting only the requests that have been successful), theMockRestServiceServer.verify()method will not let the@Testfail!Example:
The rest template sends 3 requests out, and 2 exceptions are logged (because we set up the mock with
once().So far so good, but the
MockRestServiceServerseems not to record the failed requests, and.verify()always passes! But it should fail because 3 requests have been send, instead of the expected one only.Affects: 5.0.8