Browse Source

Refine null-safety in the spring-test module

Closes gh-34161
pull/34171/head
Sébastien Deleuze 1 year ago
parent
commit
a442c180f1
  1. 2
      spring-test/src/main/java/org/springframework/test/context/jdbc/SqlScriptsTestExecutionListener.java
  2. 2
      spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java
  3. 4
      spring-test/src/main/java/org/springframework/test/context/support/AbstractDirtiesContextTestExecutionListener.java
  4. 2
      spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java
  5. 2
      spring-test/src/main/java/org/springframework/test/context/support/TestPropertySourceUtils.java
  6. 2
      spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java
  7. 1
      spring-test/src/main/java/org/springframework/test/http/MediaTypeAssert.java
  8. 2
      spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java
  9. 4
      spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java
  10. 2
      spring-test/src/main/java/org/springframework/test/web/ModelAndViewAssert.java
  11. 16
      spring-test/src/main/java/org/springframework/test/web/UriAssert.java
  12. 4
      spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java
  13. 4
      spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java
  14. 5
      spring-test/src/main/java/org/springframework/test/web/servlet/DefaultMvcResult.java
  15. 4
      spring-test/src/main/java/org/springframework/test/web/servlet/MvcResult.java
  16. 2
      spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java
  17. 4
      spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java
  18. 6
      spring-test/src/test/java/org/springframework/test/web/servlet/StubMvcResult.java
  19. 8
      spring-web/src/main/java/org/springframework/http/InvalidMediaTypeException.java

2
spring-test/src/main/java/org/springframework/test/context/jdbc/SqlScriptsTestExecutionListener.java

@ -410,7 +410,7 @@ public class SqlScriptsTestExecutionListener extends AbstractTestExecutionListen @@ -410,7 +410,7 @@ public class SqlScriptsTestExecutionListener extends AbstractTestExecutionListen
* Detect a default SQL script by implementing the algorithm defined in
* {@link Sql#scripts}.
*/
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
private String detectDefaultScript(Class<?> testClass, @Nullable Method testMethod, boolean classLevel) {
Assert.state(classLevel || testMethod != null, "Method-level @Sql requires a testMethod");

2
spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java

@ -373,7 +373,7 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes @@ -373,7 +373,7 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes
* the supplied {@link TestContextManager}.
* @since 6.1
*/
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // org.junit.jupiter.api.extension.ExecutableInvoker is not null marked
private static void registerMethodInvoker(TestContextManager testContextManager, ExtensionContext context) {
testContextManager.getTestContext().setMethodInvoker(context.getExecutableInvoker()::invoke);
}

4
spring-test/src/main/java/org/springframework/test/context/support/AbstractDirtiesContextTestExecutionListener.java

@ -84,7 +84,7 @@ public abstract class AbstractDirtiesContextTestExecutionListener extends Abstra @@ -84,7 +84,7 @@ public abstract class AbstractDirtiesContextTestExecutionListener extends Abstra
* @since 4.2
* @see #dirtyContext
*/
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
protected void beforeOrAfterTestMethod(TestContext testContext, MethodMode requiredMethodMode,
ClassMode requiredClassMode) throws Exception {
@ -136,7 +136,7 @@ public abstract class AbstractDirtiesContextTestExecutionListener extends Abstra @@ -136,7 +136,7 @@ public abstract class AbstractDirtiesContextTestExecutionListener extends Abstra
* @since 4.2
* @see #dirtyContext
*/
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
protected void beforeOrAfterTestClass(TestContext testContext, ClassMode requiredClassMode) throws Exception {
Assert.notNull(testContext, "TestContext must not be null");
Assert.notNull(requiredClassMode, "requiredClassMode must not be null");

2
spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java

@ -232,7 +232,7 @@ abstract class ContextLoaderUtils { @@ -232,7 +232,7 @@ abstract class ContextLoaderUtils {
* @throws IllegalArgumentException if the supplied class is {@code null} or if
* {@code @ContextConfiguration} is not <em>present</em> on the supplied class
*/
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
static List<ContextConfigurationAttributes> resolveContextConfigurationAttributes(Class<?> testClass) {
Assert.notNull(testClass, "Class must not be null");

2
spring-test/src/main/java/org/springframework/test/context/support/TestPropertySourceUtils.java

@ -134,7 +134,7 @@ public abstract class TestPropertySourceUtils { @@ -134,7 +134,7 @@ public abstract class TestPropertySourceUtils {
return mergedAttributes;
}
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
private static boolean duplicationDetected(TestPropertySourceAttributes currentAttributes,
@Nullable TestPropertySourceAttributes previousAttributes) {

2
spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java

@ -194,7 +194,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis @@ -194,7 +194,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
* @see #getTransactionManager(TestContext, String)
*/
@Override
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
public void beforeTestMethod(final TestContext testContext) throws Exception {
Method testMethod = testContext.getTestMethod();
Class<?> testClass = testContext.getTestClass();

1
spring-test/src/main/java/org/springframework/test/http/MediaTypeAssert.java

@ -103,7 +103,6 @@ public class MediaTypeAssert extends AbstractObjectAssert<MediaTypeAssert, Media @@ -103,7 +103,6 @@ public class MediaTypeAssert extends AbstractObjectAssert<MediaTypeAssert, Media
}
@SuppressWarnings("NullAway")
private MediaType parseMediaType(String value) {
try {
return MediaType.parseMediaType(value);

2
spring-test/src/main/java/org/springframework/test/json/AbstractJsonContentAssert.java

@ -489,7 +489,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent @@ -489,7 +489,7 @@ public abstract class AbstractJsonContentAssert<SELF extends AbstractJsonContent
return (this.actual != null ? this.actual.getJson() : null);
}
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
private String toNonNullJsonString() {
String jsonString = toJsonString();
Assertions.assertThat(jsonString).as("JSON content").isNotNull();

4
spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java

@ -173,7 +173,7 @@ public abstract class ReflectionTestUtils { @@ -173,7 +173,7 @@ public abstract class ReflectionTestUtils {
* @see ReflectionUtils#setField(Field, Object, Object)
* @see AopTestUtils#getUltimateTargetObject(Object)
*/
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
public static void setField(@Nullable Object targetObject, @Nullable Class<?> targetClass,
@Nullable String name, @Nullable Object value, @Nullable Class<?> type) {
@ -258,7 +258,7 @@ public abstract class ReflectionTestUtils { @@ -258,7 +258,7 @@ public abstract class ReflectionTestUtils {
* @see ReflectionUtils#getField(Field, Object)
* @see AopTestUtils#getUltimateTargetObject(Object)
*/
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
public static @Nullable Object getField(@Nullable Object targetObject, @Nullable Class<?> targetClass, String name) {
Assert.isTrue(targetObject != null || targetClass != null,
"Either targetObject or targetClass for the field must be specified");

2
spring-test/src/main/java/org/springframework/test/web/ModelAndViewAssert.java

@ -109,7 +109,7 @@ public abstract class ModelAndViewAssert { @@ -109,7 +109,7 @@ public abstract class ModelAndViewAssert {
* @param mav the ModelAndView to test against (never {@code null})
* @param expectedModel the expected model
*/
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
public static void assertModelAttributeValues(ModelAndView mav, Map<String, Object> expectedModel) {
Map<String, Object> model = mav.getModel();

16
spring-test/src/main/java/org/springframework/test/web/UriAssert.java

@ -80,22 +80,32 @@ public class UriAssert extends AbstractStringAssert<UriAssert> { @@ -80,22 +80,32 @@ public class UriAssert extends AbstractStringAssert<UriAssert> {
return this;
}
@SuppressWarnings("NullAway")
private String buildUri(String uriTemplate, Object... uriVars) {
try {
return UriComponentsBuilder.fromUriString(uriTemplate)
.buildAndExpand(uriVars).encode().toUriString();
}
catch (Exception ex) {
String message = ex.getMessage();
throw Failures.instance().failure(this.info,
new ShouldBeValidUriTemplate(uriTemplate, ex.getMessage()));
message == null ?
new ShouldBeValidUriTemplate(uriTemplate) :
new ShouldBeValidUriTemplateWithMessage(uriTemplate, message));
}
}
private static final class ShouldBeValidUriTemplate extends BasicErrorMessageFactory {
private ShouldBeValidUriTemplate(String uriTemplate, String errorMessage) {
private ShouldBeValidUriTemplate(String uriTemplate) {
super("%nExpecting:%n %s%nTo be a valid URI template%n", uriTemplate);
}
}
private static final class ShouldBeValidUriTemplateWithMessage extends BasicErrorMessageFactory {
private ShouldBeValidUriTemplateWithMessage(String uriTemplate, String errorMessage) {
super("%nExpecting:%n %s%nTo be a valid URI template but got:%n %s%n", uriTemplate, errorMessage);
}
}

4
spring-test/src/main/java/org/springframework/test/web/client/match/MockRestRequestMatchers.java

@ -159,7 +159,7 @@ public abstract class MockRestRequestMatchers { @@ -159,7 +159,7 @@ public abstract class MockRestRequestMatchers {
* @see #queryParam(String, String...)
*/
@SafeVarargs
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
public static RequestMatcher queryParam(String name, Matcher<? super String>... matchers) {
return request -> {
MultiValueMap<String, String> params = getQueryParams(request);
@ -187,7 +187,7 @@ public abstract class MockRestRequestMatchers { @@ -187,7 +187,7 @@ public abstract class MockRestRequestMatchers {
* @see #queryParamList(String, Matcher)
* @see #queryParam(String, Matcher...)
*/
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
public static RequestMatcher queryParam(String name, String... expectedValues) {
return request -> {
MultiValueMap<String, String> params = getQueryParams(request);

4
spring-test/src/main/java/org/springframework/test/web/reactive/server/WiretapConnector.java

@ -62,7 +62,7 @@ class WiretapConnector implements ClientHttpConnector { @@ -62,7 +62,7 @@ class WiretapConnector implements ClientHttpConnector {
@Override
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri,
Function<? super ClientHttpRequest, Mono<Void>> requestCallback) {
@ -180,7 +180,7 @@ class WiretapConnector implements ClientHttpConnector { @@ -180,7 +180,7 @@ class WiretapConnector implements ClientHttpConnector {
return this.publisherNested;
}
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
public Mono<byte[]> getContent() {
return Mono.defer(() -> {
if (this.content.scan(Scannable.Attr.TERMINATED) == Boolean.TRUE) {

5
spring-test/src/main/java/org/springframework/test/web/servlet/DefaultMvcResult.java

@ -124,13 +124,12 @@ class DefaultMvcResult implements MvcResult { @@ -124,13 +124,12 @@ class DefaultMvcResult implements MvcResult {
}
@Override
public Object getAsyncResult() {
public @Nullable Object getAsyncResult() {
return getAsyncResult(-1);
}
@Override
@SuppressWarnings("NullAway")
public Object getAsyncResult(long timeToWait) {
public @Nullable Object getAsyncResult(long timeToWait) {
if (this.mockRequest.getAsyncContext() != null && timeToWait == -1) {
long requestTimeout = this.mockRequest.getAsyncContext().getTimeout();
timeToWait = requestTimeout == -1 ? Long.MAX_VALUE : requestTimeout;

4
spring-test/src/main/java/org/springframework/test/web/servlet/MvcResult.java

@ -85,7 +85,7 @@ public interface MvcResult { @@ -85,7 +85,7 @@ public interface MvcResult {
* {@link #getAsyncResult(long)} to specify the amount of time to wait.
* @throws IllegalStateException if the async result was not set
*/
Object getAsyncResult();
@Nullable Object getAsyncResult();
/**
* Get the result of async execution and wait if necessary.
@ -96,6 +96,6 @@ public interface MvcResult { @@ -96,6 +96,6 @@ public interface MvcResult {
* MockAsyncContext#setTimeout} for more details.
* @throws IllegalStateException if the async result was not set
*/
Object getAsyncResult(long timeToWait);
@Nullable Object getAsyncResult(long timeToWait);
}

2
spring-test/src/main/java/org/springframework/test/web/servlet/assertj/MvcTestResultAssert.java

@ -212,7 +212,7 @@ public class MvcTestResultAssert extends AbstractMockHttpServletResponseAssert<M @@ -212,7 +212,7 @@ public class MvcTestResultAssert extends AbstractMockHttpServletResponseAssert<M
return this.actual.getMvcResult().getResolvedException();
}
@SuppressWarnings("NullAway")
@SuppressWarnings("NullAway") // Dataflow analysis limitation
private ModelAndView getModelAndView() {
ModelAndView modelAndView = getMvcResult().getModelAndView();
Assertions.assertThat(modelAndView).as("ModelAndView").isNotNull();

4
spring-test/src/main/java/org/springframework/test/web/servlet/client/MockMvcHttpConnector.java

@ -292,12 +292,12 @@ public class MockMvcHttpConnector implements ClientHttpConnector { @@ -292,12 +292,12 @@ public class MockMvcHttpConnector implements ClientHttpConnector {
}
@Override
public Object getAsyncResult() {
public @Nullable Object getAsyncResult() {
return this.mvcResult.getAsyncResult();
}
@Override
public Object getAsyncResult(long timeToWait) {
public @Nullable Object getAsyncResult(long timeToWait) {
return this.mvcResult.getAsyncResult(timeToWait);
}

6
spring-test/src/test/java/org/springframework/test/web/servlet/StubMvcResult.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.test.web.servlet;
import org.jspecify.annotations.Nullable;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.servlet.FlashMap;
@ -127,12 +129,12 @@ public class StubMvcResult implements MvcResult { @@ -127,12 +129,12 @@ public class StubMvcResult implements MvcResult {
}
@Override
public Object getAsyncResult() {
public @Nullable Object getAsyncResult() {
return null;
}
@Override
public Object getAsyncResult(long timeToWait) {
public @Nullable Object getAsyncResult(long timeToWait) {
return null;
}

8
spring-web/src/main/java/org/springframework/http/InvalidMediaTypeException.java

@ -51,6 +51,14 @@ public class InvalidMediaTypeException extends IllegalArgumentException { @@ -51,6 +51,14 @@ public class InvalidMediaTypeException extends IllegalArgumentException {
this.mediaType = ex.getMimeType();
}
/**
* Returns the detail message string of this exception instance (never {@code null}).
*/
@Override
@SuppressWarnings("NullAway") // InvalidMediaTypeException message is never null
public String getMessage() {
return super.getMessage();
}
/**
* Return the offending media type.

Loading…
Cancel
Save