Support for mutating ServerWebExchange in WebTestClient

This commit adds a common base class for server-less setup with the
option to configure a transformation function on the
ServerWebExchange for every request.

The transformation is applied through a WebFilter. As a result the
RouterFunction setup is now invoked behind a DispatcherHandler with
a HandlerMapping + HandlerAdapter.

Issue: SPR-15250
This commit is contained in:
Rossen Stoyanchev
2017-03-10 15:00:30 -05:00
parent 1c9d4deba2
commit f36e3d4a0d
9 changed files with 309 additions and 80 deletions

View File

@@ -17,10 +17,11 @@ package org.springframework.test.web.reactive.server;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertSame;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Unit tests for {@link DefaultControllerSpec}.
@@ -29,44 +30,47 @@ import static org.junit.Assert.assertSame;
public class DefaultControllerSpecTests {
@Test
public void controllers() throws Exception {
OneController controller1 = new OneController();
SecondController controller2 = new SecondController();
TestControllerSpec spec = new TestControllerSpec(controller1, controller2);
ApplicationContext context = spec.createApplicationContext();
assertSame(controller1, context.getBean(OneController.class));
assertSame(controller2, context.getBean(SecondController.class));
public void controller() throws Exception {
new DefaultControllerSpec(new MyController()).build()
.get().uri("/")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).value().isEqualTo("Success");
}
@Test
public void controllerAdvice() throws Exception {
OneControllerAdvice advice = new OneControllerAdvice();
TestControllerSpec spec = new TestControllerSpec(new OneController());
spec.controllerAdvice(advice);
ApplicationContext context = spec.createApplicationContext();
assertSame(advice, context.getBean(OneControllerAdvice.class));
new DefaultControllerSpec(new MyController())
.controllerAdvice(new MyControllerAdvice())
.build()
.get().uri("/exception")
.exchange()
.expectStatus().isBadRequest()
.expectBody(String.class).value().isEqualTo("Handled exception");
}
private static class OneController {}
private static class SecondController {}
@RestController
private static class MyController {
private static class OneControllerAdvice {}
private static class TestControllerSpec extends DefaultControllerSpec {
TestControllerSpec(Object... controllers) {
super(controllers);
@GetMapping("/")
public String handle() {
return "Success";
}
@Override
public AnnotationConfigApplicationContext createApplicationContext() {
return super.createApplicationContext();
@GetMapping("/exception")
public void handleWithError() {
throw new IllegalStateException();
}
}
@ControllerAdvice
private static class MyControllerAdvice {
@ExceptionHandler
public ResponseEntity<String> handle(IllegalStateException ex) {
return ResponseEntity.status(400).body("Handled exception");
}
}

View File

@@ -15,8 +15,12 @@
*/
package org.springframework.test.web.reactive.server.samples.bind;
import java.security.Principal;
import java.util.function.Function;
import org.junit.Before;
import org.junit.Test;
import reactor.core.publisher.Mono;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -25,6 +29,10 @@ import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.server.ServerWebExchange;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Binding to server infrastructure declared in a Spring ApplicationContext.
@@ -44,15 +52,26 @@ public class ApplicationContextTests {
context.register(WebConfig.class);
context.refresh();
this.client = WebTestClient.bindToApplicationContext(context).build();
this.client = WebTestClient.bindToApplicationContext(context)
.exchangeMutator(identityMutator("Pablo"))
.build();
}
private Function<ServerWebExchange, ServerWebExchange> identityMutator(String userName) {
return exchange -> {
Principal user = mock(Principal.class);
when(user.getName()).thenReturn(userName);
return exchange.mutate().principal(Mono.just(user)).build();
};
}
@Test
public void test() throws Exception {
this.client.get().uri("/test")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).value().isEqualTo("It works!");
.expectBody(String.class).value().isEqualTo("Hello Pablo!");
}
@@ -71,8 +90,8 @@ public class ApplicationContextTests {
static class TestController {
@GetMapping("/test")
public String handle() {
return "It works!";
public String handle(Principal principal) {
return "Hello " + principal.getName() + "!";
}
}

View File

@@ -15,12 +15,20 @@
*/
package org.springframework.test.web.reactive.server.samples.bind;
import java.security.Principal;
import java.util.function.Function;
import org.junit.Before;
import org.junit.Test;
import reactor.core.publisher.Mono;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Bind to annotated controllers.
@@ -35,7 +43,18 @@ public class ControllerTests {
@Before
public void setUp() throws Exception {
this.client = WebTestClient.bindToController(new TestController()).build();
this.client = WebTestClient.bindToController(new TestController())
.exchangeMutator(identityMutator("Pablo"))
.build();
}
private Function<ServerWebExchange, ServerWebExchange> identityMutator(String userName) {
return exchange -> {
Principal user = mock(Principal.class);
when(user.getName()).thenReturn(userName);
return exchange.mutate().principal(Mono.just(user)).build();
};
}
@@ -44,7 +63,7 @@ public class ControllerTests {
this.client.get().uri("/test")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).value().isEqualTo("It works!");
.expectBody(String.class).value().isEqualTo("Hello Pablo!");
}
@@ -52,8 +71,9 @@ public class ControllerTests {
static class TestController {
@GetMapping("/test")
public String handle() {
return "It works!";
public String handle(Principal principal) {
return "Hello " + principal.getName() + "!";
}
}
}