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:
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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() + "!";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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() + "!";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user