The goal is to verify that the expected interactions occur up to the given timeout. This is useful for testing asynchronous flows in event-driven services, similar to the testing support in Spring Amqp.
Sample code:
@SpringBootApplication
public class MyApplication {
@Autowired
private RestTemplate template;
@RabbitListener()
public void callService(String payload) {
template.put("http://example.com/hello", payload);
}
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class ApplicationTest {
@Autowired
private MockRestServiceServer mockServer;
@Autowired
private AmqpTemplate template;
@Test
public void callsService() {
mockServer.expect(method(PUT))
.andExpect(requestTo("/hello"))
.andRespond(withNoContent());
template.convertAndSend("HelloWorld");
mockServer.verify(5, TimeUnit.SECONDS);
}
}
Comment From: sbrannen
@rstoyanchev, what do you think about adding this?
Comment From: rstoyanchev
How would this work specifically, check if expectations > 0 and if so wait for up to the specified time, but otherwise fail early in case of failures?
Comment From: kewne
My mental model of mockServer.verify
is that it goes through the list of expectations, checking if they match the recorded interactions.
In the synchronous case, it either succeeds because all expectations matched or fails because they didn't.
In the asynchronous case, it would loop, checking for 4 possibilities: 1. All the expectations matched, return; 2. One of the expectations failed because, e.g., you expected a POST followed by a GET but recorded a POST followed by another POST (I'm assuming call order is verified as well, otherwise the interaction might happen later/out of order and you fall into the next case); 3. Not all expectations matched but the recorded interactions so far are matches, in which case it waits and retries; 4. The timeout was reached without all expectations being matched.
In essence, something like this but more polished: ```java success = false; while (elapsed() < timeout && !success) { try { verify(); success = true; } catch (Exception e) { // ignore failed verifications } } if (!success) { throw TimeoutException(); }
Comment From: rstoyanchev
Expectations are ordered by default but that can be turned off. In any case, regardless of the ExpectationManager
used, it comes down to a list of expectations all of which should be satisfied. If any fail, there would be a failure recorded immediately. This should be fairly straight forward to implement. I'll give it a try.