Skip to content

Instantly share code, notes, and snippets.

@guillermocalvo
Last active November 12, 2019 07:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guillermocalvo/740b4fcab471ebc6fe69227fee6d79d5 to your computer and use it in GitHub Desktop.
Save guillermocalvo/740b4fcab471ebc6fe69227fee6d79d5 to your computer and use it in GitHub Desktop.
Testing Web Filter
package test.webfilter;
import static org.springframework.boot.WebApplicationType.REACTIVE;
import static test.webfilter.WebFilterTest.eventsGet;
import static test.webfilter.WebFilterTest.eventsPost;
import java.util.List;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import test.webfilter.TestApplication.TestController;
import test.webfilter.TestApplication.TestWebFilter;
@SpringBootApplication
@Import({ TestWebFilter.class, TestController.class })
@Configuration
public class TestApplication {
@RestController
@RequestMapping
public static class TestController {
@GetMapping(value = "/mono-get")
public Mono<String> monoGet(ServerWebExchange exchange) {
eventsGet.add("CONTROLLER-GET");
return Mono
.just("FOOBAR")
.doOnEach(s -> eventsGet.add("MONO-GET-" + s))
.map(e -> "OK")
.doOnEach(s -> eventsGet.add("MONO-GET-" + s));
}
@PostMapping(value = "/mono-post")
public Mono<String> monoPost(ServerWebExchange exchange, @RequestBody Mono<String> text) {
eventsPost.add("CONTROLLER-POST");
return text
.doOnEach(s -> eventsPost.add("MONO-POST-" + s))
.map(s -> "OK")
.doOnEach(s -> eventsPost.add("MONO-POST-" + s));
}
}
// Test Web Filter
public static class TestWebFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
final ServerHttpRequest request = exchange.getRequest();
final ServerHttpResponse response = exchange.getResponse();
final List<String> events = request.getURI().getPath().equals("/mono-get") ? eventsGet : eventsPost;
return chain.filter(exchange)
.doOnSubscribe(s -> events.add("FILTER-BEFORE-CHAIN/commited=" + response.isCommitted()))
.doOnEach(s -> events.add("FILTER-AFTER-CHAIN/commited=" + response.isCommitted()))
.doFinally(s -> events.add("FILTER-FINALLY/commited=" + response.isCommitted()));
}
}
public static void main(String[] args) {
new SpringApplicationBuilder(TestApplication.class).web(REACTIVE).build().run(args);
}
}
package test.webfilter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static java.util.Collections.synchronizedList;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.reactive.function.BodyInserters;
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = { TestApplication.class })
public class WebFilterTest {
static List<String> eventsGet;
static List<String> eventsPost;
@LocalServerPort
int port;
@Autowired
WebTestClient webTestClient;
@Test
public void testMonoGet() {
// Given
eventsGet = synchronizedList(new ArrayList<>());
eventsGet.add("START-GET");
// When/Then
webTestClient
.get()
.uri("http://localhost:" + port + "/mono-get")
.exchange()
.expectStatus()
.isOk()
.expectBody(String.class)
.isEqualTo("OK");
// Verify order of events
assertThat(eventsGet).containsExactly(
"START-GET",
"FILTER-BEFORE-CHAIN/commited=false",
"CONTROLLER-GET",
"MONO-GET-doOnEach_onNext(FOOBAR)",
"MONO-GET-onComplete()",
"MONO-GET-doOnEach_onNext(OK)",
"MONO-GET-onComplete()",
"FILTER-AFTER-CHAIN/commited=true",
"FILTER-FINALLY/commited=true"
);
}
@Test
public void testMonoPost() {
// Given
eventsPost = synchronizedList(new ArrayList<>());
eventsPost.add("START-POST");
// When/Then
webTestClient
.post()
.uri("http://localhost:" + port + "/mono-post")
.body(BodyInserters
.fromObject("HELLO"))
.exchange()
.expectStatus()
.isOk()
.expectBody(String.class)
.isEqualTo("OK");
// Verify order of events
assertThat(eventsPost).containsExactly(
"START-POST",
"FILTER-BEFORE-CHAIN/commited=false",
"CONTROLLER-POST",
"MONO-POST-doOnEach_onNext(HELLO)",
"MONO-POST-onComplete()",
"MONO-POST-doOnEach_onNext(OK)",
"MONO-POST-onComplete()",
"FILTER-AFTER-CHAIN/commited=true",
"FILTER-FINALLY/commited=true"
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment