Verified correct behavior of RestController for 404
[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.server.ResponseStatusException;
15 import reactor.core.publisher.Mono;
16 import reactor.test.StepVerifier;
17
18
19 /**
20  * Unit-Test for class {@link RestController}.
21  * @author Kai Moritz
22  */
23 public class RestControllerTest
24 {
25   RestController controller;
26   RemoteContentService service;
27
28
29   @BeforeEach
30   void setUp()
31   {
32     service = Mockito.mock(RemoteContentService.class);
33     controller = new RestController(service);
34   }
35
36
37   @Test
38   @DisplayName("Data successfully fetched from remote-server")
39   void testResponseOK()
40   {
41     when(service.getRemoteText("foo")).thenReturn(Mono.just("bar"));
42
43     Mono<String> result = controller.fetch("foo");
44
45     StepVerifier
46         .create(result)
47         .expectNext("bar")
48         .expectComplete()
49         .verify();
50   }
51
52   @Test
53   @DisplayName("Data not found on remote-server")
54   void testResponseNotFoud()
55   {
56     when(service.getRemoteText("foo")).thenReturn(Mono.error(exception(404)));
57
58     Mono<String> result = controller.fetch("foo");
59
60     StepVerifier
61         .create(result)
62         .expectErrorSatisfies((t) ->
63         {
64           assertThat(t).isInstanceOf(ResponseStatusException.class);
65           ResponseStatusException status = (ResponseStatusException)t;
66           assertThat(status.getStatus()).isEqualTo(HttpStatus.NOT_FOUND);
67           assertThat(t.getMessage()).startsWith("404 NOT_FOUND \"Cause: 404 MESSAGE\";");
68         })
69         .verify();
70   }
71
72   /**
73    * Only the behavior on the common errors, as defined in {@link
74    * WebClientResponseException#create(int, String, org.springframework.http.HttpHeaders, byte[], java.nio.charset.Charset, org.springframework.http.HttpRequest)
75    * WebClientResponseException.create()} is tested.
76    */
77   @DisplayName("Other error while fetching data from remote-server")
78   @ParameterizedTest(name = "{arguments} ==> HTTP-status={0}")
79   @EnumSource(value = HttpStatus.class, names = {
80     "BAD_REQUEST",
81     "UNAUTHORIZED",
82     "FORBIDDEN",
83     "METHOD_NOT_ALLOWED",
84     "NOT_ACCEPTABLE",
85     "CONFLICT",
86     "GONE",
87     "UNSUPPORTED_MEDIA_TYPE",
88     "TOO_MANY_REQUESTS",
89     "UNPROCESSABLE_ENTITY",
90     "INTERNAL_SERVER_ERROR",
91     "NOT_IMPLEMENTED",
92     "BAD_GATEWAY",
93     "SERVICE_UNAVAILABLE",
94     "GATEWAY_TIMEOUT"
95   })
96   void testResponseOtherErrors(HttpStatus status)
97   {
98     Mono<String> mono = Mono.error(exception(status.value()));
99     when(service.getRemoteText("foo")).thenReturn(mono);
100
101     Mono<String> result = controller.fetch("foo");
102
103     StepVerifier
104         .create(result)
105         .expectErrorSatisfies((t) ->
106         {
107           assertThat(t).isInstanceOf(ResponseStatusException.class);
108           ResponseStatusException e = (ResponseStatusException)t;
109           assertThat(e.getStatus()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE);
110           assertThat(t.getMessage())
111               .startsWith(
112                   "503 SERVICE_UNAVAILABLE \"Cause: " +
113                   Integer.toString(status.value()) +
114                   " MESSAGE\";");
115         })
116         .verify();
117   }
118
119   @Test
120   @DisplayName("Internal error while fetching data from remote-server")
121   void testOtherErrors()
122   {
123     Mono<String> mono = Mono.error(new RuntimeException("Boom!"));
124     when(service.getRemoteText("foo")).thenReturn(mono);
125
126     Mono<String> result = controller.fetch("foo");
127
128     StepVerifier
129         .create(result)
130         .expectErrorSatisfies((t) ->
131         {
132           assertThat(t).isInstanceOf(ResponseStatusException.class);
133           ResponseStatusException e = (ResponseStatusException)t;
134           assertThat(e.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR);
135           assertThat(t.getMessage()).startsWith("500 INTERNAL_SERVER_ERROR \"Cause: Boom!\";");
136         })
137         .verify();
138   }
139
140
141   WebClientResponseException exception(int status)
142   {
143     return WebClientResponseException.create(status, "MESSAGE", null, null, null);
144   }
145 }