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.