Skip to content

Instantly share code, notes, and snippets.

View bjerat's full-sized avatar

Benedikt Jerat bjerat

  • Digital Frontiers GmbH & Co. KG
View GitHub Profile
class InventoryClientTest {
private InventoryClient cut;
public static MockWebServer mockBackEnd;
@BeforeAll
public static void setUp() throws IOException {
mockBackEnd = new MockWebServer();
mockBackEnd.start();
@GetExchange
List<CharacterResponse> getByName(@RequestParam String lastName);
// vs.
public List<CharacterResponse> getByName(String lastName) {
return webClient
.get()
.uri(uriBuilder -> uriBuilder
.path("/characters")
@bjerat
bjerat / Usage.java
Last active January 13, 2023 13:12
CharacterResponse brandon = characterClient.addCharacter(new AddCharacterRequest("Brandon", "Stark"));
List<CharacterResponse> starks = characterClient.getByName("Stark");
Optional<CharacterResponse> eddardStark = characterClient.getById(1);
Optional<CharacterResponse> unknown = characterClient.getById(1337L); // empty
characterClient.deleteById(brandon.id());
@Configuration
public class CharacterClientConfig {
@Bean
public CharacterClient characterClient(CharacterClientProperties properties) {
WebClient webClient = WebClient.builder()
.baseUrl(properties.getUrl())
.defaultStatusHandler(
httpStatusCode -> HttpStatus.NOT_FOUND == httpStatusCode,
response -> Mono.empty())
@HttpExchange(
url = "/characters",
accept = MediaType.APPLICATION_JSON_VALUE)
public interface CharacterClient {
@GetExchange
List<CharacterResponse> getByName(@RequestParam String lastName);
@GetExchange("/{id}")
Optional<CharacterResponse> getById(@PathVariable long id);
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Mono<InventoryEntry> result = cut.getByName(expectedEntry.name());
StepVerifier
.withVirtualTime(() -> result)
// ...
retrySpec = Retry.backoff(
inventoryClientProperties.getRetry().getMaxAttempts(),
inventoryClientProperties.getRetry().getBackoffDuration()
)
@Test
public void verifyGetByNameRecoversFromServerFailuresWithVirtualTime() {
InventoryEntry expectedEntry = new InventoryEntry(42, "Der lange Weg zu einem kleinen zornigen Planeten", 5);
mockBackEnd.enqueue(assembleResponseWithStatusCode(500));
mockBackEnd.enqueue(assembleResponse(expectedEntry));
StepVerifier
.withVirtualTime(() -> cut.getByName(expectedEntry.name()))
.expectSubscription()
@Test
public void verifyGetByNameRecoversFromServerFailuresWithBlock() {
InventoryEntry expectedEntry = new InventoryEntry(42, "Der lange Weg zu einem kleinen zornigen Planeten", 5);
mockBackEnd.enqueue(assembleResponseWithStatusCode(500));
mockBackEnd.enqueue(assembleResponse(expectedEntry));
InventoryEntry actualEntry = cut
.getByName(expectedEntry.name())
.block();