Skip to content

Commit

Permalink
Add verify(Duration) to MockRestServiceServer
Browse files Browse the repository at this point in the history
Closes gh-22618
  • Loading branch information
rstoyanchev committed Jan 13, 2021
1 parent a7413ea commit 35225e5
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,6 +18,8 @@

import java.io.IOException;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -144,25 +146,42 @@ protected RequestExpectation matchRequest(ClientHttpRequest request) throws IOEx

@Override
public void verify() {
if (this.expectations.isEmpty()) {
return;
}
int count = 0;
for (RequestExpectation expectation : this.expectations) {
if (!expectation.isSatisfied()) {
count++;
}
}
int count = verifyInternal();
if (count > 0) {
String message = "Further request(s) expected leaving " + count + " unsatisfied expectation(s).\n";
throw new AssertionError(message + getRequestDetails());
}
}

@Override
public void verify(Duration timeout) {
Instant endTime = Instant.now().plus(timeout);
do {
if (verifyInternal() == 0) {
return;
}
}
while (Instant.now().isBefore(endTime));
verify();
}

private int verifyInternal() {
if (this.expectations.isEmpty()) {
return 0;
}
if (!this.requestFailures.isEmpty()) {
throw new AssertionError("Some requests did not execute successfully.\n" +
this.requestFailures.entrySet().stream()
.map(entry -> "Failed request:\n" + entry.getKey() + "\n" + entry.getValue())
.collect(Collectors.joining("\n", "\n", "")));
}
int count = 0;
for (RequestExpectation expectation : this.expectations) {
if (!expectation.isSatisfied()) {
count++;
}
}
return count;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,6 +18,7 @@

import java.io.IOException;
import java.net.URI;
import java.time.Duration;

import org.springframework.http.HttpMethod;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
Expand Down Expand Up @@ -110,12 +111,25 @@ public ResponseActions expect(ExpectedCount count, RequestMatcher matcher) {
/**
* Verify that all expected requests set up via
* {@link #expect(RequestMatcher)} were indeed performed.
* @throws AssertionError when some expectations were not met
* @throws AssertionError if not all expectations are met
*/
public void verify() {
this.expectationManager.verify();
}

/**
* Variant of {@link #verify()} that waits for up to the specified time for
* all expectations to be fulfilled. This can be useful for tests that
* involve asynchronous requests.
* @param timeout how long to wait for all expecations to be met
* @throws AssertionError if not all expectations are met by the specified
* timeout, or if any expectation fails at any time before that.
* @since 5.3.4
*/
public void verify(Duration timeout) {
this.expectationManager.verify(timeout);
}

/**
* Reset the internal state removing all expectations and recorded requests.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@
package org.springframework.test.web.client;

import java.io.IOException;
import java.time.Duration;

import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse;
Expand Down Expand Up @@ -52,11 +53,22 @@ public interface RequestExpectationManager {
/**
* Verify that all expectations have been met.
* <p>This is a delegate for {@link MockRestServiceServer#verify()}.
* @throws AssertionError when some expectations were not met
* @throws AssertionError if not all expectations are met
* @see MockRestServiceServer#verify()
*/
void verify();

/**
* Variant of {@link #verify()} that waits for up to the specified time for
* all expectations to be fulfilled. This can be useful for tests that
* involve asynchronous requests.
* @param timeout how long to wait for all expecations to be met
* @throws AssertionError if not all expectations are met by the specified
* timeout, or if any expectation fails at any time before that.
* @since 5.3.4
*/
void verify(Duration timeout);

/**
* Reset the internal state removing all expectations and recorded requests.
* <p>This is a delegate for {@link MockRestServiceServer#reset()}.
Expand All @@ -75,5 +87,4 @@ public interface RequestExpectationManager {
* @throws IOException in case of any validation errors
*/
ClientHttpResponse validateRequest(ClientHttpRequest request) throws IOException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
package org.springframework.test.web.client;

import java.net.SocketException;
import java.time.Duration;

import org.junit.jupiter.api.Test;

import org.springframework.test.web.client.MockRestServiceServer.MockRestServiceServerBuilder;
import org.springframework.web.client.RestTemplate;

import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.fail;
import static org.springframework.http.HttpMethod.POST;
import static org.springframework.test.web.client.ExpectedCount.once;
Expand Down Expand Up @@ -171,4 +173,27 @@ public void verifyShouldFailIfRequestsFailed() {
.withMessageStartingWith("Some requests did not execute successfully");
}

@Test
public void verifyWithTimeout() {
MockRestServiceServerBuilder builder = MockRestServiceServer.bindTo(this.restTemplate);

MockRestServiceServer server1 = builder.build();
server1.expect(requestTo("/foo")).andRespond(withSuccess());
server1.expect(requestTo("/bar")).andRespond(withSuccess());
this.restTemplate.getForObject("/foo", Void.class);

assertThatThrownBy(() -> server1.verify(Duration.ofMillis(100))).hasMessage(
"Further request(s) expected leaving 1 unsatisfied expectation(s).\n" +
"1 request(s) executed:\n" +
"GET /foo, headers: [Accept:\"application/json, application/*+json\"]\n");

MockRestServiceServer server2 = builder.build();
server2.expect(requestTo("/foo")).andRespond(withSuccess());
server2.expect(requestTo("/bar")).andRespond(withSuccess());
this.restTemplate.getForObject("/foo", Void.class);
this.restTemplate.getForObject("/bar", Void.class);

server2.verify(Duration.ofMillis(100));
}

}

0 comments on commit 35225e5

Please sign in to comment.