From 33b6dca2a6d56398626ecc663ed8f54b9415d66b Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 5 Jul 2016 18:14:47 -0400 Subject: [PATCH] Polish tests --- .../reactive/DispatcherHandlerErrorTests.java | 119 ++++++------------ .../ResponseStatusExceptionHandlerTests.java | 26 ++-- ...pleUrlHandlerMappingIntegrationTests.java} | 114 ++++++----------- 3 files changed, 85 insertions(+), 174 deletions(-) rename spring-web-reactive/src/test/java/org/springframework/web/reactive/result/{WebHandlerIntegrationTests.java => SimpleUrlHandlerMappingIntegrationTests.java} (57%) diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/DispatcherHandlerErrorTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/DispatcherHandlerErrorTests.java index 3657fd2fc4f..cbd70fab9ca 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/DispatcherHandlerErrorTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/DispatcherHandlerErrorTests.java @@ -23,14 +23,12 @@ import org.junit.Before; import org.junit.Test; import org.reactivestreams.Publisher; import reactor.core.publisher.Mono; -import reactor.core.publisher.Signal; -import reactor.core.util.SignalKind; +import reactor.core.test.TestSubscriber; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.codec.StringEncoder; -import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DefaultDataBufferFactory; @@ -38,7 +36,6 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.converter.reactive.CodecHttpMessageConverter; -import org.springframework.http.converter.reactive.HttpMessageConverter; import org.springframework.http.server.reactive.MockServerHttpRequest; import org.springframework.http.server.reactive.MockServerHttpResponse; import org.springframework.stereotype.Controller; @@ -52,14 +49,10 @@ import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebExceptionHandler; -import org.springframework.web.server.WebFilter; -import org.springframework.web.server.WebFilterChain; import org.springframework.web.server.WebHandler; import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.handler.ExceptionHandlingWebHandler; -import org.springframework.web.server.handler.FilteringWebHandler; import org.springframework.web.server.session.MockWebSessionManager; -import org.springframework.web.server.session.WebSessionManager; import static org.hamcrest.CoreMatchers.startsWith; import static org.junit.Assert.assertEquals; @@ -75,15 +68,13 @@ import static org.junit.Assert.assertThat; @SuppressWarnings({"ThrowableResultOfMethodCallIgnored", "ThrowableInstanceNeverThrown"}) public class DispatcherHandlerErrorTests { - public static final IllegalStateException EXCEPTION = new IllegalStateException("boo"); + private static final IllegalStateException EXCEPTION = new IllegalStateException("boo"); private DispatcherHandler dispatcherHandler; private MockServerHttpRequest request; - private MockServerHttpResponse response; - private ServerWebExchange exchange; @@ -96,127 +87,101 @@ public class DispatcherHandlerErrorTests { this.dispatcherHandler = new DispatcherHandler(); this.dispatcherHandler.setApplicationContext(appContext); - WebSessionManager sessionManager = new MockWebSessionManager(); - this.request = new MockServerHttpRequest(HttpMethod.GET, new URI("/")); - this.response = new MockServerHttpResponse(); - this.exchange = new DefaultServerWebExchange(this.request, this.response, sessionManager); + MockServerHttpResponse response = new MockServerHttpResponse(); + MockWebSessionManager sessionManager = new MockWebSessionManager(); + this.exchange = new DefaultServerWebExchange(this.request, response, sessionManager); } @Test public void noHandler() throws Exception { this.request.setUri(new URI("/does-not-exist")); - Mono publisher = this.dispatcherHandler.handle(this.exchange); - Throwable ex = awaitErrorSignal(publisher); - assertEquals(ResponseStatusException.class, ex.getClass()); - assertEquals(HttpStatus.NOT_FOUND, ((ResponseStatusException) ex).getStatus()); + TestSubscriber.subscribe(publisher) + .assertError(ResponseStatusException.class) + .assertErrorMessage("Request failure [status: 404, reason: \"No matching handler\"]"); } @Test - public void noResolverForArgument() throws Exception { + public void unknownMethodArgumentType() throws Exception { this.request.setUri(new URI("/unknown-argument-type")); - Mono publisher = this.dispatcherHandler.handle(this.exchange); - Throwable ex = awaitErrorSignal(publisher); - assertEquals(IllegalStateException.class, ex.getClass()); - assertThat(ex.getMessage(), startsWith("No resolver for argument [0]")); + TestSubscriber.subscribe(publisher) + .assertError(IllegalStateException.class) + .assertErrorWith(ex -> assertThat(ex.getMessage(), startsWith("No resolver for argument [0]"))); } @Test - public void controllerMethodError() throws Exception { + public void controllerReturnsMonoError() throws Exception { this.request.setUri(new URI("/error-signal")); - Mono publisher = this.dispatcherHandler.handle(this.exchange); - Throwable ex = awaitErrorSignal(publisher); - assertSame(EXCEPTION, ex); + TestSubscriber.subscribe(publisher) + .assertErrorWith(ex -> assertSame(EXCEPTION, ex)); } @Test - public void controllerMethodWithThrownException() throws Exception { + public void controllerThrowsException() throws Exception { this.request.setUri(new URI("/raise-exception")); - Mono publisher = this.dispatcherHandler.handle(this.exchange); - Throwable ex = awaitErrorSignal(publisher); - assertSame(EXCEPTION, ex); + TestSubscriber.subscribe(publisher) + .assertErrorWith(ex -> assertSame(EXCEPTION, ex)); } @Test - public void noHandlerResultHandler() throws Exception { + public void unknownReturnType() throws Exception { this.request.setUri(new URI("/unknown-return-type")); - Mono publisher = this.dispatcherHandler.handle(this.exchange); - Throwable ex = awaitErrorSignal(publisher); - assertEquals(IllegalStateException.class, ex.getClass()); - assertThat(ex.getMessage(), startsWith("No HandlerResultHandler")); + TestSubscriber.subscribe(publisher) + .assertError(IllegalStateException.class) + .assertErrorWith(ex -> assertThat(ex.getMessage(), startsWith("No HandlerResultHandler"))); } @Test - public void notAcceptable() throws Exception { + public void responseBodyMessageConversionError() throws Exception { + DataBuffer dataBuffer = new DefaultDataBufferFactory().allocateBuffer(); this.request.setUri(new URI("/request-body")); - this.request.getHeaders().setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - DataBuffer buffer = new DefaultDataBufferFactory().allocateBuffer() - .write("body".getBytes("UTF-8")); - this.request.writeWith(Mono.just(buffer)); + this.request.getHeaders().add("Accept", MediaType.APPLICATION_JSON_VALUE); + this.request.writeWith(Mono.just(dataBuffer.write("body".getBytes("UTF-8")))); Mono publisher = this.dispatcherHandler.handle(this.exchange); - Throwable ex = awaitErrorSignal(publisher); - assertEquals(NotAcceptableStatusException.class, ex.getClass()); + TestSubscriber.subscribe(publisher) + .assertError(NotAcceptableStatusException.class); } @Test public void requestBodyError() throws Exception { this.request.setUri(new URI("/request-body")); this.request.writeWith(Mono.error(EXCEPTION)); - Mono publisher = this.dispatcherHandler.handle(this.exchange); - Throwable ex = awaitErrorSignal(publisher); - ex.printStackTrace(); - assertSame(EXCEPTION, ex); + TestSubscriber.subscribe(publisher) + .assertErrorWith(ex -> assertSame(EXCEPTION, ex)); } @Test - public void dispatcherHandlerWithHttpExceptionHandler() throws Exception { + public void webExceptionHandler() throws Exception { this.request.setUri(new URI("/unknown-argument-type")); WebExceptionHandler exceptionHandler = new ServerError500ExceptionHandler(); WebHandler webHandler = new ExceptionHandlingWebHandler(this.dispatcherHandler, exceptionHandler); Mono publisher = webHandler.handle(this.exchange); - publisher.block(); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, this.response.getStatusCode()); - } - - @Test - public void filterChainWithHttpExceptionHandler() throws Exception { - this.request.setUri(new URI("/unknown-argument-type")); + TestSubscriber.subscribe(publisher) + .assertErrorWith(ex -> assertEquals( + HttpStatus.INTERNAL_SERVER_ERROR, this.exchange.getResponse().getStatusCode())); - WebHandler webHandler = new FilteringWebHandler(this.dispatcherHandler, new TestWebFilter()); - webHandler = new ExceptionHandlingWebHandler(webHandler, new ServerError500ExceptionHandler()); - Mono publisher = webHandler.handle(this.exchange); - - publisher.block(); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, this.response.getStatusCode()); - } - - - private Throwable awaitErrorSignal(Mono mono) throws Exception { - Signal signal = mono.materialize().block(); - assertEquals("Unexpected signal: " + signal, SignalKind.onError, signal.getType()); - return signal.getThrowable(); } @Configuration - @SuppressWarnings("unused") + @SuppressWarnings({"unused", "WeakerAccess"}) static class TestConfig { @Bean @@ -231,9 +196,9 @@ public class DispatcherHandlerErrorTests { @Bean public ResponseBodyResultHandler resultHandler() { - HttpMessageConverter converter = new CodecHttpMessageConverter<>(new StringEncoder()); - ConversionService conversionService = new DefaultConversionService(); - return new ResponseBodyResultHandler(Collections.singletonList(converter), conversionService); + return new ResponseBodyResultHandler( + Collections.singletonList(new CodecHttpMessageConverter<>(new StringEncoder())), + new DefaultConversionService()); } @Bean @@ -285,12 +250,4 @@ public class DispatcherHandlerErrorTests { } } - private static class TestWebFilter implements WebFilter { - - @Override - public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { - return chain.filter(exchange); - } - } - } diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/ResponseStatusExceptionHandlerTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/ResponseStatusExceptionHandlerTests.java index c44553b96f2..704a713008e 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/ResponseStatusExceptionHandlerTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/ResponseStatusExceptionHandlerTests.java @@ -16,11 +16,12 @@ package org.springframework.web.reactive; import java.net.URI; +import java.time.Duration; import org.junit.Before; import org.junit.Test; import reactor.core.publisher.Mono; -import reactor.core.publisher.Signal; +import reactor.core.test.TestSubscriber; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -30,12 +31,9 @@ import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.adapter.DefaultServerWebExchange; import org.springframework.web.server.session.MockWebSessionManager; -import org.springframework.web.server.session.WebSessionManager; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; /** * Unit tests for {@link ResponseStatusExceptionHandler}. @@ -54,31 +52,29 @@ public class ResponseStatusExceptionHandlerTests { @Before public void setUp() throws Exception { this.handler = new ResponseStatusExceptionHandler(); - MockServerHttpRequest request = new MockServerHttpRequest(HttpMethod.GET, new URI("/path")); - WebSessionManager sessionManager = new MockWebSessionManager(); this.response = new MockServerHttpResponse(); - this.exchange = new DefaultServerWebExchange(request, this.response, sessionManager); + this.exchange = new DefaultServerWebExchange( + new MockServerHttpRequest(HttpMethod.GET, new URI("/path")), + this.response, + new MockWebSessionManager()); } @Test public void handleException() throws Exception { Throwable ex = new ResponseStatusException(HttpStatus.BAD_REQUEST, ""); - Mono publisher = this.handler.handle(this.exchange, ex); + this.handler.handle(this.exchange, ex).block(Duration.ofSeconds(5)); - publisher.block(); assertEquals(HttpStatus.BAD_REQUEST, this.response.getStatusCode()); } @Test public void unresolvedException() throws Exception { - Throwable ex = new IllegalStateException(); - Mono publisher = this.handler.handle(this.exchange, ex); + Throwable expected = new IllegalStateException(); + Mono mono = this.handler.handle(this.exchange, expected); - Signal signal = publisher.materialize().block(); - assertNotNull(signal); - assertTrue(signal.hasError()); - assertSame(ex, signal.getThrowable()); + TestSubscriber.subscribe(mono) + .assertErrorWith(actual -> assertSame(expected, actual)); } } diff --git a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/WebHandlerIntegrationTests.java b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/SimpleUrlHandlerMappingIntegrationTests.java similarity index 57% rename from spring-web-reactive/src/test/java/org/springframework/web/reactive/result/WebHandlerIntegrationTests.java rename to spring-web-reactive/src/test/java/org/springframework/web/reactive/result/SimpleUrlHandlerMappingIntegrationTests.java index 73c45012ae0..5b1c2730381 100644 --- a/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/WebHandlerIntegrationTests.java +++ b/spring-web-reactive/src/test/java/org/springframework/web/reactive/result/SimpleUrlHandlerMappingIntegrationTests.java @@ -17,7 +17,6 @@ package org.springframework.web.reactive.result; import java.net.URI; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; @@ -31,6 +30,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DefaultDataBuffer; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.http.HttpStatus; import org.springframework.http.RequestEntity; @@ -42,27 +42,22 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.DispatcherHandler; import org.springframework.web.reactive.ResponseStatusExceptionHandler; import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; -import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebHandler; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; - /** - * Integration tests with requests mapped to plain {@link WebHandler}s. + * Integration tests with requests mapped via + * {@link SimpleUrlHandlerMapping} to plain {@link WebHandler}s. * * @author Rossen Stoyanchev */ -public class WebHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests { - - private static final Charset UTF_8 = Charset.forName("UTF-8"); - +public class SimpleUrlHandlerMappingIntegrationTests extends AbstractHttpHandlerIntegrationTests { @Override protected HttpHandler createHttpHandler() { - AnnotationConfigApplicationContext wac = new AnnotationConfigApplicationContext(); wac.register(WebConfig.class); wac.refresh(); @@ -76,109 +71,73 @@ public class WebHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTe } @Test - public void testFooHandler() throws Exception { - - RestTemplate restTemplate = new RestTemplate(); - - URI url = new URI("http://localhost:" + port + "/foo"); + public void testRequestToFooHandler() throws Exception { + URI url = new URI("http://localhost:" + this.port + "/foo"); RequestEntity request = RequestEntity.get(url).build(); - ResponseEntity response = restTemplate.exchange(request, byte[].class); + ResponseEntity response = new RestTemplate().exchange(request, byte[].class); assertEquals(HttpStatus.OK, response.getStatusCode()); - assertArrayEquals("foo".getBytes(UTF_8), response.getBody()); + assertArrayEquals("foo".getBytes("UTF-8"), response.getBody()); } @Test - public void testBarHandler() throws Exception { - - RestTemplate restTemplate = new RestTemplate(); - - URI url = new URI("http://localhost:" + port + "/bar"); + public void testRequestToBarHandler() throws Exception { + URI url = new URI("http://localhost:" + this.port + "/bar"); RequestEntity request = RequestEntity.get(url).build(); - ResponseEntity response = restTemplate.exchange(request, byte[].class); + ResponseEntity response = new RestTemplate().exchange(request, byte[].class); assertEquals(HttpStatus.OK, response.getStatusCode()); - assertArrayEquals("bar".getBytes(UTF_8), response.getBody()); + assertArrayEquals("bar".getBytes("UTF-8"), response.getBody()); } @Test - public void testHeaderSettingHandler() throws Exception { - - RestTemplate restTemplate = new RestTemplate(); - - URI url = new URI("http://localhost:" + port + "/header"); + public void testRequestToHeaderSettingHandler() throws Exception { + URI url = new URI("http://localhost:" + this.port + "/header"); RequestEntity request = RequestEntity.get(url).build(); - ResponseEntity response = restTemplate.exchange(request, byte[].class); + ResponseEntity response = new RestTemplate().exchange(request, byte[].class); assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals("bar", response.getHeaders().getFirst("foo")); } @Test - public void testNotFound() throws Exception { - - RestTemplate restTemplate = new RestTemplate(); - - URI url = new URI("http://localhost:" + port + "/oops"); + public void testHandlerNotFound() throws Exception { + URI url = new URI("http://localhost:" + this.port + "/oops"); RequestEntity request = RequestEntity.get(url).build(); try { - restTemplate.exchange(request, byte[].class); + new RestTemplate().exchange(request, byte[].class); } catch (HttpClientErrorException ex) { assertEquals(HttpStatus.NOT_FOUND, ex.getStatusCode()); } } - - private static class TestSimpleUrlHandlerMapping extends SimpleUrlHandlerMapping { - - public TestSimpleUrlHandlerMapping() { - Map map = new HashMap<>(); - map.put("/foo", new FooHandler()); - map.put("/bar", new BarHandler()); - map.put("/header", new HeaderSettingHandler()); - setUrlMap(map); - } - } - private static DataBuffer asDataBuffer(String text) { - return new DefaultDataBufferFactory().allocateBuffer() - .write(text.getBytes(StandardCharsets.UTF_8)); - } - - private static class FooHandler implements WebHandler { - - @Override - public Mono handle(ServerWebExchange exchange) { - DataBuffer buffer = asDataBuffer("foo"); - return exchange.getResponse().writeWith(Flux.just(buffer)); - } - } - - private static class BarHandler implements WebHandler { - - @Override - public Mono handle(ServerWebExchange exchange) { - DataBuffer buffer = asDataBuffer("bar"); - return exchange.getResponse().writeWith(Flux.just(buffer)); - } + DefaultDataBuffer buffer = new DefaultDataBufferFactory().allocateBuffer(); + return buffer.write(text.getBytes(StandardCharsets.UTF_8)); } - private static class HeaderSettingHandler implements WebHandler { - - @Override - public Mono handle(ServerWebExchange exchange) { - exchange.getResponse().getHeaders().add("foo", "bar"); - return Mono.empty(); - } - } @Configuration + @SuppressWarnings({"unused", "WeakerAccess"}) static class WebConfig { @Bean - public TestSimpleUrlHandlerMapping handlerMapping() { - return new TestSimpleUrlHandlerMapping(); + public SimpleUrlHandlerMapping handlerMapping() { + return new SimpleUrlHandlerMapping() { + { + Map map = new HashMap<>(); + map.put("/foo", (WebHandler) exchange -> + exchange.getResponse().writeWith(Flux.just(asDataBuffer("foo")))); + map.put("/bar", (WebHandler) exchange -> + exchange.getResponse().writeWith(Flux.just(asDataBuffer("bar")))); + map.put("/header", (WebHandler) exchange -> { + exchange.getResponse().getHeaders().add("foo", "bar"); + return Mono.empty(); + }); + setUrlMap(map); + } + }; } @Bean @@ -190,7 +149,6 @@ public class WebHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTe public SimpleResultHandler resultHandler() { return new SimpleResultHandler(new DefaultConversionService()); } - } }