Skip to content

Commit b4ffe15

Browse files
committed
Separate Testing Reactive Docs
Issue gh-10367
1 parent d779cd1 commit b4ffe15

File tree

8 files changed

+282
-274
lines changed

8 files changed

+282
-274
lines changed

docs/modules/ROOT/nav.adoc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,11 @@
103103
** Integrations
104104
*** xref:reactive/integrations/cors.adoc[CORS]
105105
*** xref:reactive/integrations/rsocket.adoc[RSocket]
106-
** xref:reactive/test.adoc[Testing]
106+
** xref:reactive/test/index.adoc[Testing]
107+
*** xref:reactive/test/method.adoc[Testing Method Security]
108+
*** xref:reactive/test/web/index.adoc[Testing Web Security]
109+
**** xref:reactive/test/web/setup.adoc[WebTestClient Setup]
110+
**** xref:reactive/test/web/authentication.adoc[Testing Authentication]
111+
**** xref:reactive/test/web/csrf.adoc[Testing CSRF]
112+
**** xref:reactive/test/web/oauth2.adoc[Testing OAuth 2.0]
107113
** xref:reactive/configuration/webflux.adoc[WebFlux Security]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[[test-webflux]]
2+
= Reactive Test Support
3+
:page-section-summary-toc: 1
4+
5+
Spring Security supports two basic modes for testing reactive applications.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
[[test-erms]]
2+
= Testing Method Security
3+
4+
For example, we can test our example from xref:reactive/authorization/method.adoc#jc-erms[EnableReactiveMethodSecurity] using the same setup and annotations we did in xref:servlet/test/method.adoc#test-method[Testing Method Security].
5+
Here is a minimal sample of what we can do:
6+
7+
====
8+
.Java
9+
[source,java,role="primary"]
10+
----
11+
@RunWith(SpringRunner.class)
12+
@ContextConfiguration(classes = HelloWebfluxMethodApplication.class)
13+
public class HelloWorldMessageServiceTests {
14+
@Autowired
15+
HelloWorldMessageService messages;
16+
17+
@Test
18+
public void messagesWhenNotAuthenticatedThenDenied() {
19+
StepVerifier.create(this.messages.findMessage())
20+
.expectError(AccessDeniedException.class)
21+
.verify();
22+
}
23+
24+
@Test
25+
@WithMockUser
26+
public void messagesWhenUserThenDenied() {
27+
StepVerifier.create(this.messages.findMessage())
28+
.expectError(AccessDeniedException.class)
29+
.verify();
30+
}
31+
32+
@Test
33+
@WithMockUser(roles = "ADMIN")
34+
public void messagesWhenAdminThenOk() {
35+
StepVerifier.create(this.messages.findMessage())
36+
.expectNext("Hello World!")
37+
.verifyComplete();
38+
}
39+
}
40+
----
41+
42+
.Kotlin
43+
[source,kotlin,role="secondary"]
44+
----
45+
@RunWith(SpringRunner::class)
46+
@ContextConfiguration(classes = [HelloWebfluxMethodApplication::class])
47+
class HelloWorldMessageServiceTests {
48+
@Autowired
49+
lateinit var messages: HelloWorldMessageService
50+
51+
@Test
52+
fun messagesWhenNotAuthenticatedThenDenied() {
53+
StepVerifier.create(messages.findMessage())
54+
.expectError(AccessDeniedException::class.java)
55+
.verify()
56+
}
57+
58+
@Test
59+
@WithMockUser
60+
fun messagesWhenUserThenDenied() {
61+
StepVerifier.create(messages.findMessage())
62+
.expectError(AccessDeniedException::class.java)
63+
.verify()
64+
}
65+
66+
@Test
67+
@WithMockUser(roles = ["ADMIN"])
68+
fun messagesWhenAdminThenOk() {
69+
StepVerifier.create(messages.findMessage())
70+
.expectNext("Hello World!")
71+
.verifyComplete()
72+
}
73+
}
74+
----
75+
====
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
= Testing Authentication
2+
3+
After xref:reactive/test/web/setup.adoc[applying the Spring Security support to `WebTestClient`] we can use either annotations or `mutateWith` support.
4+
For example:
5+
6+
====
7+
.Java
8+
[source,java,role="primary"]
9+
----
10+
@Test
11+
public void messageWhenNotAuthenticated() throws Exception {
12+
this.rest
13+
.get()
14+
.uri("/message")
15+
.exchange()
16+
.expectStatus().isUnauthorized();
17+
}
18+
19+
// --- WithMockUser ---
20+
21+
@Test
22+
@WithMockUser
23+
public void messageWhenWithMockUserThenForbidden() throws Exception {
24+
this.rest
25+
.get()
26+
.uri("/message")
27+
.exchange()
28+
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN);
29+
}
30+
31+
@Test
32+
@WithMockUser(roles = "ADMIN")
33+
public void messageWhenWithMockAdminThenOk() throws Exception {
34+
this.rest
35+
.get()
36+
.uri("/message")
37+
.exchange()
38+
.expectStatus().isOk()
39+
.expectBody(String.class).isEqualTo("Hello World!");
40+
}
41+
42+
// --- mutateWith mockUser ---
43+
44+
@Test
45+
public void messageWhenMutateWithMockUserThenForbidden() throws Exception {
46+
this.rest
47+
.mutateWith(mockUser())
48+
.get()
49+
.uri("/message")
50+
.exchange()
51+
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN);
52+
}
53+
54+
@Test
55+
public void messageWhenMutateWithMockAdminThenOk() throws Exception {
56+
this.rest
57+
.mutateWith(mockUser().roles("ADMIN"))
58+
.get()
59+
.uri("/message")
60+
.exchange()
61+
.expectStatus().isOk()
62+
.expectBody(String.class).isEqualTo("Hello World!");
63+
}
64+
----
65+
66+
.Kotlin
67+
[source,kotlin,role="secondary"]
68+
----
69+
import org.springframework.test.web.reactive.server.expectBody
70+
71+
//...
72+
73+
@Test
74+
@WithMockUser
75+
fun messageWhenWithMockUserThenForbidden() {
76+
this.rest.get().uri("/message")
77+
.exchange()
78+
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN)
79+
}
80+
81+
@Test
82+
@WithMockUser(roles = ["ADMIN"])
83+
fun messageWhenWithMockAdminThenOk() {
84+
this.rest.get().uri("/message")
85+
.exchange()
86+
.expectStatus().isOk
87+
.expectBody<String>().isEqualTo("Hello World!")
88+
89+
}
90+
91+
// --- mutateWith mockUser ---
92+
93+
@Test
94+
fun messageWhenMutateWithMockUserThenForbidden() {
95+
this.rest
96+
.mutateWith(mockUser())
97+
.get().uri("/message")
98+
.exchange()
99+
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN)
100+
}
101+
102+
@Test
103+
fun messageWhenMutateWithMockAdminThenOk() {
104+
this.rest
105+
.mutateWith(mockUser().roles("ADMIN"))
106+
.get().uri("/message")
107+
.exchange()
108+
.expectStatus().isOk
109+
.expectBody<String>().isEqualTo("Hello World!")
110+
}
111+
----
112+
====
113+
114+
In addition to `mockUser()`, Spring Security ships with several other convenience mutators for things like xref:reactive/test/web/csrf.adoc[CSRF] and xref:reactive/test/web/oauth2.adoc[OAuth 2.0].
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
= Testing with CSRF
2+
3+
Spring Security also provides support for CSRF testing with `WebTestClient`.
4+
For example:
5+
6+
====
7+
.Java
8+
[source,java,role="primary"]
9+
----
10+
this.rest
11+
// provide a valid CSRF token
12+
.mutateWith(csrf())
13+
.post()
14+
.uri("/login")
15+
...
16+
----
17+
18+
.Kotlin
19+
[source,kotlin,role="secondary"]
20+
----
21+
this.rest
22+
// provide a valid CSRF token
23+
.mutateWith(csrf())
24+
.post()
25+
.uri("/login")
26+
...
27+
----
28+
====
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[[test-webtestclient]]
2+
= Testing Web Security
3+
:page-section-summary-toc: 1
4+
5+
In this section, we'll talk about testing web application endpoints.

0 commit comments

Comments
 (0)