Skip to content

Commit c2156d6

Browse files
committed
Remove static state from CF web endpoint integration tests
The mocks being static meant that their state was shared across each test in the class. This resulted in the tests being order dependent. This commit uses instance variables to hold the mocks, thereby ensuring that they're recreated for each test as part of the standard JUnit lifecycle. Closes gh-38363
1 parent 9b8bcec commit c2156d6

File tree

2 files changed

+36
-35
lines changed

2 files changed

+36
-35
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,23 @@
7575
*/
7676
class CloudFoundryWebFluxEndpointIntegrationTests {
7777

78-
private static ReactiveTokenValidator tokenValidator = mock(ReactiveTokenValidator.class);
78+
private final ReactiveTokenValidator tokenValidator = mock(ReactiveTokenValidator.class);
7979

80-
private static ReactiveCloudFoundrySecurityService securityService = mock(
81-
ReactiveCloudFoundrySecurityService.class);
80+
private final ReactiveCloudFoundrySecurityService securityService = mock(ReactiveCloudFoundrySecurityService.class);
8281

8382
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner(
8483
AnnotationConfigReactiveWebServerApplicationContext::new)
8584
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class, HttpHandlerAutoConfiguration.class,
8685
ReactiveWebServerFactoryAutoConfiguration.class))
8786
.withUserConfiguration(TestEndpointConfiguration.class)
87+
.withBean(ReactiveTokenValidator.class, () -> this.tokenValidator)
88+
.withBean(ReactiveCloudFoundrySecurityService.class, () -> this.securityService)
8889
.withPropertyValues("server.port=0");
8990

9091
@Test
9192
void operationWithSecurityInterceptorForbidden() {
92-
given(tokenValidator.validate(any())).willReturn(Mono.empty());
93-
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
93+
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
94+
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
9495
this.contextRunner.run(withWebTestClient((client) -> client.get()
9596
.uri("/cfApplication/test")
9697
.accept(MediaType.APPLICATION_JSON)
@@ -102,8 +103,8 @@ void operationWithSecurityInterceptorForbidden() {
102103

103104
@Test
104105
void operationWithSecurityInterceptorSuccess() {
105-
given(tokenValidator.validate(any())).willReturn(Mono.empty());
106-
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
106+
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
107+
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
107108
this.contextRunner.run(withWebTestClient((client) -> client.get()
108109
.uri("/cfApplication/test")
109110
.accept(MediaType.APPLICATION_JSON)
@@ -131,8 +132,8 @@ void responseToOptionsRequestIncludesCorsHeaders() {
131132

132133
@Test
133134
void linksToOtherEndpointsWithFullAccess() {
134-
given(tokenValidator.validate(any())).willReturn(Mono.empty());
135-
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
135+
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
136+
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
136137
this.contextRunner.run(withWebTestClient((client) -> client.get()
137138
.uri("/cfApplication")
138139
.accept(MediaType.APPLICATION_JSON)
@@ -169,7 +170,7 @@ void linksToOtherEndpointsWithFullAccess() {
169170
void linksToOtherEndpointsForbidden() {
170171
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
171172
"invalid-token");
172-
willThrow(exception).given(tokenValidator).validate(any());
173+
willThrow(exception).given(this.tokenValidator).validate(any());
173174
this.contextRunner.run(withWebTestClient((client) -> client.get()
174175
.uri("/cfApplication")
175176
.accept(MediaType.APPLICATION_JSON)
@@ -181,8 +182,8 @@ void linksToOtherEndpointsForbidden() {
181182

182183
@Test
183184
void linksToOtherEndpointsWithRestrictedAccess() {
184-
given(tokenValidator.validate(any())).willReturn(Mono.empty());
185-
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
185+
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
186+
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.RESTRICTED));
186187
this.contextRunner.run(withWebTestClient((client) -> client.get()
187188
.uri("/cfApplication")
188189
.accept(MediaType.APPLICATION_JSON)
@@ -232,7 +233,8 @@ private String mockAccessToken() {
232233
static class CloudFoundryReactiveConfiguration {
233234

234235
@Bean
235-
CloudFoundrySecurityInterceptor interceptor() {
236+
CloudFoundrySecurityInterceptor interceptor(ReactiveTokenValidator tokenValidator,
237+
ReactiveCloudFoundrySecurityService securityService) {
236238
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
237239
}
238240

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryMvcWebEndpointIntegrationTests.java

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
4343
import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint;
4444
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer;
45+
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
4546
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
4647
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
4748
import org.springframework.context.ApplicationContext;
@@ -70,13 +71,13 @@
7071
*/
7172
class CloudFoundryMvcWebEndpointIntegrationTests {
7273

73-
private static TokenValidator tokenValidator = mock(TokenValidator.class);
74+
private final TokenValidator tokenValidator = mock(TokenValidator.class);
7475

75-
private static CloudFoundrySecurityService securityService = mock(CloudFoundrySecurityService.class);
76+
private final CloudFoundrySecurityService securityService = mock(CloudFoundrySecurityService.class);
7677

7778
@Test
7879
void operationWithSecurityInterceptorForbidden() {
79-
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
80+
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
8081
load(TestEndpointConfiguration.class,
8182
(client) -> client.get()
8283
.uri("/cfApplication/test")
@@ -89,7 +90,7 @@ void operationWithSecurityInterceptorForbidden() {
8990

9091
@Test
9192
void operationWithSecurityInterceptorSuccess() {
92-
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
93+
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
9394
load(TestEndpointConfiguration.class,
9495
(client) -> client.get()
9596
.uri("/cfApplication/test")
@@ -119,7 +120,7 @@ void responseToOptionsRequestIncludesCorsHeaders() {
119120

120121
@Test
121122
void linksToOtherEndpointsWithFullAccess() {
122-
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
123+
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.FULL);
123124
load(TestEndpointConfiguration.class,
124125
(client) -> client.get()
125126
.uri("/cfApplication")
@@ -157,7 +158,7 @@ void linksToOtherEndpointsWithFullAccess() {
157158
void linksToOtherEndpointsForbidden() {
158159
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
159160
"invalid-token");
160-
willThrow(exception).given(tokenValidator).validate(any());
161+
willThrow(exception).given(this.tokenValidator).validate(any());
161162
load(TestEndpointConfiguration.class,
162163
(client) -> client.get()
163164
.uri("/cfApplication")
@@ -170,7 +171,7 @@ void linksToOtherEndpointsForbidden() {
170171

171172
@Test
172173
void linksToOtherEndpointsWithRestrictedAccess() {
173-
given(securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
174+
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(AccessLevel.RESTRICTED);
174175
load(TestEndpointConfiguration.class,
175176
(client) -> client.get()
176177
.uri("/cfApplication")
@@ -198,26 +199,23 @@ void linksToOtherEndpointsWithRestrictedAccess() {
198199
.doesNotExist());
199200
}
200201

201-
private AnnotationConfigServletWebServerApplicationContext createApplicationContext(Class<?>... config) {
202-
return new AnnotationConfigServletWebServerApplicationContext(config);
202+
private void load(Class<?> configuration, Consumer<WebTestClient> clientConsumer) {
203+
BiConsumer<ApplicationContext, WebTestClient> consumer = (context, client) -> clientConsumer.accept(client);
204+
new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
205+
.withUserConfiguration(configuration, CloudFoundryMvcConfiguration.class)
206+
.withBean(TokenValidator.class, () -> this.tokenValidator)
207+
.withBean(CloudFoundrySecurityService.class, () -> this.securityService)
208+
.run((context) -> consumer.accept(context, WebTestClient.bindToServer()
209+
.baseUrl("http://localhost:" + getPort(
210+
(AnnotationConfigServletWebServerApplicationContext) context.getSourceApplicationContext()))
211+
.responseTimeout(Duration.ofMinutes(5))
212+
.build()));
203213
}
204214

205215
private int getPort(AnnotationConfigServletWebServerApplicationContext context) {
206216
return context.getWebServer().getPort();
207217
}
208218

209-
private void load(Class<?> configuration, Consumer<WebTestClient> clientConsumer) {
210-
BiConsumer<ApplicationContext, WebTestClient> consumer = (context, client) -> clientConsumer.accept(client);
211-
try (AnnotationConfigServletWebServerApplicationContext context = createApplicationContext(configuration,
212-
CloudFoundryMvcConfiguration.class)) {
213-
consumer.accept(context,
214-
WebTestClient.bindToServer()
215-
.baseUrl("http://localhost:" + getPort(context))
216-
.responseTimeout(Duration.ofMinutes(5))
217-
.build());
218-
}
219-
}
220-
221219
private String mockAccessToken() {
222220
return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwu"
223221
+ "Y29tIiwiZXhwIjoxNDI2NDIwODAwLCJhd2Vzb21lIjp0cnVlfQ."
@@ -229,7 +227,8 @@ private String mockAccessToken() {
229227
static class CloudFoundryMvcConfiguration {
230228

231229
@Bean
232-
CloudFoundrySecurityInterceptor interceptor() {
230+
CloudFoundrySecurityInterceptor interceptor(TokenValidator tokenValidator,
231+
CloudFoundrySecurityService securityService) {
233232
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService, "app-id");
234233
}
235234

0 commit comments

Comments
 (0)