4b4526a7b20a41d0085217ac593bbc2bec7b493f
[demos/testing] / src / test / java / de / juplo / demo / RestControllerTest.java
1 package de.juplo.demo;
2
3
4 import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
5 import org.junit.jupiter.api.BeforeEach;
6 import org.junit.jupiter.api.DisplayName;
7 import org.junit.jupiter.api.Test;
8 import org.junit.jupiter.params.ParameterizedTest;
9 import org.junit.jupiter.params.provider.EnumSource;
10 import org.mockito.Mockito;
11 import static org.mockito.Mockito.when;
12 import org.springframework.http.HttpStatus;
13 import org.springframework.web.reactive.function.client.WebClientResponseException;
14 import org.springframework.web.reactive.function.client.WebClientResponseException.NotFound;
15 import org.springframework.web.reactive.function.client.WebClientResponseException.ServiceUnavailable;
16 import reactor.core.publisher.Mono;
17 import reactor.test.StepVerifier;
18
19
20 /**
21  * Unit-Test for class {@link RestController}.
22  * @author Kai Moritz
23  */
24 public class RestControllerTest
25 {
26   RestController controller;
27   RemoteContentService service;
28
29
30   @BeforeEach
31   void setUp()
32   {
33     service = Mockito.mock(RemoteContentService.class);
34     controller = new RestController(service);
35   }
36
37
38   @Test
39   @DisplayName("Data successfully fetched from remote-server")
40   void testResponseOK()
41   {
42     when(service.getRemoteText("foo")).thenReturn(Mono.just("bar"));
43
44     Mono<String> result = controller.fetch("foo");
45
46     StepVerifier
47         .create(result)
48         .expectNext("bar")
49         .expectComplete()
50         .verify();
51   }
52
53   @Test
54   @DisplayName("Data not found on remote-server")
55   void testResponseNotFoud()
56   {
57     when(service.getRemoteText("foo")).thenReturn(Mono.error(exception(404)));
58
59     Mono<String> result = controller.fetch("foo");
60
61     StepVerifier
62         .create(result)
63         .expectError(NotFound.class)
64         .verify();
65   }
66
67   /**
68    * Only the behavior on the common errors, as defined in {@link
69    * WebClientResponseException#create(int, String, org.springframework.http.HttpHeaders, byte[], java.nio.charset.Charset, org.springframework.http.HttpRequest)
70    * WebClientResponseException.create()} is tested.
71    */
72   @DisplayName("Other error while fetching data from remote-server")
73   @ParameterizedTest(name = "{arguments} ==> HTTP-status={0}")
74   @EnumSource(value = HttpStatus.class, names = {
75     "BAD_REQUEST",
76     "UNAUTHORIZED",
77     "FORBIDDEN",
78     "METHOD_NOT_ALLOWED",
79     "NOT_ACCEPTABLE",
80     "CONFLICT",
81     "GONE",
82     "UNSUPPORTED_MEDIA_TYPE",
83     "TOO_MANY_REQUESTS",
84     "UNPROCESSABLE_ENTITY",
85     "INTERNAL_SERVER_ERROR",
86     "NOT_IMPLEMENTED",
87     "BAD_GATEWAY",
88     "SERVICE_UNAVAILABLE",
89     "GATEWAY_TIMEOUT"
90   })
91   void testResponseOtherErrors(HttpStatus status)
92   {
93     Mono<String> mono = Mono.error(exception(status.value()));
94     when(service.getRemoteText("foo")).thenReturn(mono);
95
96     Mono<String> result = controller.fetch("foo");
97
98     StepVerifier
99         .create(result)
100         .expectErrorSatisfies((t) ->
101         {
102           assertThat(t).isInstanceOf(ServiceUnavailable.class);
103           assertThat(t.getMessage())
104               .startsWith(
105                   "503 Service Unavailable - Cause: " +
106                   Integer.toString(status.value()));
107         })
108         .verify();
109   }
110
111
112   WebClientResponseException exception(int status)
113   {
114     return WebClientResponseException.create(status, "", null, null, null);
115   }
116 }