Skip to content

Commit a82e545

Browse files
committed
adding tests
1 parent 93da6f8 commit a82e545

File tree

5 files changed

+72
-28
lines changed

5 files changed

+72
-28
lines changed

spring-cloud-modules/spring-cloud-openfeign-2/src/main/java/com/baeldung/cloud/openfeign/completablefuturefeignclient/PaymentMethodClient.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
import org.springframework.web.bind.annotation.RequestMethod;
66
import org.springframework.web.bind.annotation.RequestParam;
77

8-
import java.util.List;
9-
108
@FeignClient(name = "paymentClient", url = "http://localhost:8083")
119
public interface PaymentMethodClient {
1210

spring-cloud-modules/spring-cloud-openfeign-2/src/main/java/com/baeldung/cloud/openfeign/completablefuturefeignclient/Purchase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
public class Purchase {
44

5-
private String siteId;
5+
String siteId;
66

77
public Purchase(String siteId) {
88
this.siteId = siteId;
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package com.baeldung.cloud.openfeign.completablefuturefeignclient;
22

33
import feign.FeignException;
4+
import feign.RetryableException;
45
import org.springframework.stereotype.Service;
56

6-
import java.util.List;
77
import java.util.concurrent.CompletableFuture;
88
import java.util.concurrent.ExecutionException;
99
import java.util.concurrent.TimeUnit;
10-
11-
import static java.lang.String.format;
10+
import java.util.concurrent.TimeoutException;
1211

1312
@Service
1413
public class PurchaseService {
@@ -23,24 +22,28 @@ public PurchaseService(PaymentMethodClient paymentMethodClient, ReportClient rep
2322

2423
public String executePurchase(Purchase purchase) throws ExecutionException, InterruptedException {
2524
CompletableFuture<String> paymentMethodsFuture = CompletableFuture.supplyAsync(() -> paymentMethodClient.processPurchase(purchase.getSiteId()))
26-
.handle((res, ex) -> {
27-
if (ex.getCause() instanceof FeignException) {
28-
int status = ((FeignException) ex.getCause()).status();
25+
.orTimeout(400, TimeUnit.MILLISECONDS)
26+
.exceptionally(ex -> {
27+
if (ex.getCause() instanceof FeignException && ((FeignException) ex.getCause()).status() == 404) {
28+
return "account_money";
29+
}
2930

30-
if (status == 404) {
31-
return null;
32-
}
31+
if (ex.getCause() instanceof RetryableException) {
32+
// handle REST timeout
33+
throw new RuntimeException("REST call network timeout!");
3334
}
34-
return res;
35-
})
36-
.orTimeout(2, TimeUnit.SECONDS);
3735

38-
CompletableFuture<Void> reportFuture = CompletableFuture.runAsync(() -> reportClient.sendReport("Purchase Order Report"))
39-
.orTimeout(1, TimeUnit.SECONDS);
36+
if (ex instanceof TimeoutException) {
37+
// handle thread timeout
38+
throw new RuntimeException("Thread timeout!", ex);
39+
}
40+
41+
throw new RuntimeException("Unrecoverable error!", ex);
42+
});
4043

41-
CompletableFuture.allOf(paymentMethodsFuture, reportFuture)
42-
.join();
44+
CompletableFuture.runAsync(() -> reportClient.sendReport("Purchase Order Report"))
45+
.orTimeout(1, TimeUnit.SECONDS);
4346

44-
return paymentMethodsFuture.get();
47+
return String.format("Purchase executed with payment method %s", paymentMethodsFuture.get());
4548
}
4649
}

spring-cloud-modules/spring-cloud-openfeign-2/src/test/java/com/baeldung/cloud/openfeign/completablefuturefeignclient/PurchaseServiceIntegrationTest.java

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,21 @@
88
import org.junit.jupiter.api.extension.ExtendWith;
99
import org.springframework.beans.factory.annotation.Autowired;
1010
import org.springframework.boot.test.context.SpringBootTest;
11+
import org.springframework.cloud.openfeign.FeignClientProperties;
1112
import org.springframework.http.HttpStatus;
13+
import org.springframework.test.context.TestPropertySource;
1214
import org.springframework.test.context.junit.jupiter.SpringExtension;
1315

1416
import java.util.concurrent.ExecutionException;
17+
import java.util.concurrent.TimeoutException;
1518

1619
import static com.github.tomakehurst.wiremock.client.WireMock.*;
17-
import static org.junit.Assert.assertNull;
18-
import static org.junit.Assert.assertThrows;
20+
import static org.junit.Assert.*;
1921
import static org.mockito.ArgumentMatchers.any;
2022

2123
@ExtendWith(SpringExtension.class)
2224
@SpringBootTest(classes = ExampleApplication.class)
25+
@TestPropertySource(locations = "classpath:application-integration_test.properties")
2326
class PurchaseServiceIntegrationTest {
2427

2528
@Autowired
@@ -33,11 +36,18 @@ class PurchaseServiceIntegrationTest {
3336

3437
private WireMockServer wireMockServer;
3538

39+
private Purchase purchase;
40+
3641
@BeforeEach
3742
public void startWireMockServer() {
3843
wireMockServer = new WireMockServer(8083);
3944
configureFor("localhost", 8083);
4045
wireMockServer.start();
46+
47+
stubFor(post(urlEqualTo("/reports"))
48+
.willReturn(aResponse().withStatus(HttpStatus.OK.value())));
49+
50+
purchase = new Purchase("BR");
4151
}
4252

4353
@AfterEach
@@ -46,17 +56,46 @@ public void stopWireMockServer() {
4656
}
4757

4858
@Test
49-
void executePurchase() throws ExecutionException, InterruptedException {
59+
void givenRestCalls_whenBothReturnsOk_thenReturnCorrectResult()
60+
throws ExecutionException, InterruptedException {
5061
stubFor(post(urlEqualTo("/purchase?site_id=BR"))
51-
.willReturn(aResponse().withStatus(HttpStatus.NOT_FOUND.value())));
62+
.willReturn(aResponse().withStatus(HttpStatus.OK.value()).withBody("credit_card")));
5263

53-
stubFor(post(urlEqualTo("/reports"))
54-
.willReturn(aResponse().withStatus(HttpStatus.OK.value())));
64+
String result = purchaseService.executePurchase(purchase);
5565

56-
Purchase purchase = new Purchase("BR");
66+
assertNotNull(result);
67+
assertEquals("Purchase executed with payment method credit_card", result);
68+
}
69+
70+
@Test
71+
void givenRestCalls_whenPurchaseReturns404_thenReturnDefault()
72+
throws ExecutionException, InterruptedException {
73+
stubFor(post(urlEqualTo("/purchase?site_id=BR"))
74+
.willReturn(aResponse().withStatus(HttpStatus.NOT_FOUND.value())));
5775

5876
String result = purchaseService.executePurchase(purchase);
5977

60-
assertNull(result);
78+
assertNotNull(result);
79+
assertEquals("Purchase executed with payment method account_money", result);
80+
}
81+
82+
@Test
83+
void givenRestCalls_whenPurchaseCompletableFutureTimeout_thenReturnDefault() {
84+
stubFor(post(urlEqualTo("/purchase?site_id=BR"))
85+
.willReturn(aResponse().withFixedDelay(450)));
86+
87+
Throwable error = assertThrows(ExecutionException.class, () -> purchaseService.executePurchase(purchase));
88+
89+
assertEquals("java.lang.RuntimeException: Thread timeout!", error.getMessage());
6190
}
91+
92+
// @Test
93+
// void givenRestCalls_whenPurchaseRequestWebTimeout_thenReturnDefault() {
94+
// stubFor(post(urlEqualTo("/purchase?site_id=BR"))
95+
// .willReturn(aResponse().withFixedDelay(250)));
96+
//
97+
// Throwable error = assertThrows(ExecutionException.class, () -> purchaseService.executePurchase(purchase));
98+
//
99+
// assertEquals("REST call network timeout!", error.getMessage());
100+
// }
62101
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
feign.client.config.PaymentMethodClient.readTimeout: 200
2+
feign.client.config.PaymentMethodClient.connectTimeout: 50
3+
feign.client.config.ReportClient.readTimeout: 100
4+
feign.client.config.ReportClient.connectTimeout: 50

0 commit comments

Comments
 (0)