Add nullability annotations to tests in core/spring-boot-test

See gh-47263
This commit is contained in:
Moritz Halbritter
2025-10-02 12:12:44 +02:00
parent 23c9b6510b
commit ea05f6df15
33 changed files with 176 additions and 76 deletions
+3
View File
@@ -62,3 +62,6 @@ dependencies {
testRuntimeOnly("org.junit.vintage:junit-vintage-engine")
}
tasks.named("compileTestJava") {
options.nullability.checking = "tests"
}
@@ -35,12 +35,14 @@ class AnnotatedClassFinderTests {
private final AnnotatedClassFinder finder = new AnnotatedClassFinder(SpringBootConfiguration.class);
@Test
@SuppressWarnings("NullAway") // Test null check
void findFromClassWhenSourceIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> this.finder.findFromClass((Class<?>) null))
.withMessageContaining("'source' must not be null");
}
@Test
@SuppressWarnings("NullAway") // Test null check
void findFromPackageWhenSourceIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> this.finder.findFromPackage((String) null))
.withMessageContaining("'source' must not be null");
@@ -41,6 +41,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
class AnnotationsPropertySourceTests {
@Test
@SuppressWarnings("NullAway") // Test null check
void createWhenSourceIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> new AnnotationsPropertySource(null))
.withMessageContaining("Property source must not be null");
@@ -18,6 +18,7 @@ package org.springframework.boot.test.context;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import org.junit.jupiter.api.Test;
@@ -46,29 +47,35 @@ class ImportsContextCustomizerFactoryTests {
@Test
void getContextCustomizerWhenHasNoImportAnnotationShouldReturnNull() {
ContextCustomizer customizer = this.factory.createContextCustomizer(TestWithNoImport.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(TestWithNoImport.class,
Collections.emptyList());
assertThat(customizer).isNull();
}
@Test
void getContextCustomizerWhenHasImportAnnotationShouldReturnCustomizer() {
ContextCustomizer customizer = this.factory.createContextCustomizer(TestWithImport.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(TestWithImport.class,
Collections.emptyList());
assertThat(customizer).isNotNull();
}
@Test
void getContextCustomizerWhenHasMetaImportAnnotationShouldReturnCustomizer() {
ContextCustomizer customizer = this.factory.createContextCustomizer(TestWithMetaImport.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(TestWithMetaImport.class,
Collections.emptyList());
assertThat(customizer).isNotNull();
}
@Test
void contextCustomizerEqualsAndHashCode() {
ContextCustomizer customizer1 = this.factory.createContextCustomizer(TestWithImport.class, null);
ContextCustomizer customizer2 = this.factory.createContextCustomizer(TestWithImport.class, null);
ContextCustomizer customizer3 = this.factory.createContextCustomizer(TestWithImportAndMetaImport.class, null);
ContextCustomizer customizer1 = this.factory.createContextCustomizer(TestWithImport.class,
Collections.emptyList());
ContextCustomizer customizer2 = this.factory.createContextCustomizer(TestWithImport.class,
Collections.emptyList());
ContextCustomizer customizer3 = this.factory.createContextCustomizer(TestWithImportAndMetaImport.class,
Collections.emptyList());
ContextCustomizer customizer4 = this.factory.createContextCustomizer(TestWithSameImportAndMetaImport.class,
null);
Collections.emptyList());
assertThat(customizer1).hasSameHashCodeAs(customizer1);
assertThat(customizer1).hasSameHashCodeAs(customizer2);
assertThat(customizer1).isEqualTo(customizer1).isEqualTo(customizer2).isNotEqualTo(customizer3);
@@ -78,11 +85,11 @@ class ImportsContextCustomizerFactoryTests {
@Test
void contextCustomizerEqualsAndHashCodeConsidersComponentScan() {
ContextCustomizer customizer1 = this.factory
.createContextCustomizer(TestWithImportAndComponentScanOfSomePackage.class, null);
.createContextCustomizer(TestWithImportAndComponentScanOfSomePackage.class, Collections.emptyList());
ContextCustomizer customizer2 = this.factory
.createContextCustomizer(TestWithImportAndComponentScanOfSomePackage.class, null);
.createContextCustomizer(TestWithImportAndComponentScanOfSomePackage.class, Collections.emptyList());
ContextCustomizer customizer3 = this.factory
.createContextCustomizer(TestWithImportAndComponentScanOfAnotherPackage.class, null);
.createContextCustomizer(TestWithImportAndComponentScanOfAnotherPackage.class, Collections.emptyList());
assertThat(customizer1).isEqualTo(customizer2);
assertThat(customizer1).hasSameHashCodeAs(customizer2);
assertThat(customizer3).isNotEqualTo(customizer2).isNotEqualTo(customizer1);
@@ -91,15 +98,17 @@ class ImportsContextCustomizerFactoryTests {
@Test
void getContextCustomizerWhenClassHasBeanMethodsShouldThrowException() {
assertThatIllegalStateException()
.isThrownBy(() -> this.factory.createContextCustomizer(TestWithImportAndBeanMethod.class, null))
assertThatIllegalStateException().isThrownBy(
() -> this.factory.createContextCustomizer(TestWithImportAndBeanMethod.class, Collections.emptyList()))
.withMessageContaining("Test classes cannot include @Bean methods");
}
@Test
void contextCustomizerImportsBeans() {
ContextCustomizer customizer = this.factory.createContextCustomizer(TestWithImport.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(TestWithImport.class,
Collections.emptyList());
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
assertThat(customizer).isNotNull();
customizer.customizeContext(context, mock(MergedContextConfiguration.class));
context.refresh();
assertThat(context.getBean(ImportedBean.class)).isNotNull();
@@ -107,7 +116,8 @@ class ImportsContextCustomizerFactoryTests {
@Test
void selfAnnotatingAnnotationDoesNotCauseStackOverflow() {
assertThat(this.factory.createContextCustomizer(TestWithImportAndSelfAnnotatingAnnotation.class, null))
assertThat(this.factory.createContextCustomizer(TestWithImportAndSelfAnnotatingAnnotation.class,
Collections.emptyList()))
.isNotNull();
}
@@ -18,6 +18,7 @@ package org.springframework.boot.test.context;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import org.junit.jupiter.api.Test;
@@ -28,6 +29,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextLoader;
import org.springframework.test.context.MergedContextConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -46,57 +49,67 @@ class PropertyMappingContextCustomizerFactoryTests {
@Test
void getContextCustomizerWhenHasNoMappingShouldNotAddPropertySource() {
ContextCustomizer customizer = this.factory.createContextCustomizer(NoMapping.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(NoMapping.class, Collections.emptyList());
ConfigurableApplicationContext context = mock(ConfigurableApplicationContext.class);
ConfigurableEnvironment environment = mock(ConfigurableEnvironment.class);
ConfigurableListableBeanFactory beanFactory = mock(ConfigurableListableBeanFactory.class);
given(context.getEnvironment()).willReturn(environment);
given(context.getBeanFactory()).willReturn(beanFactory);
customizer.customizeContext(context, null);
customizer.customizeContext(context, getMergedConfigConfiguration());
then(environment).shouldHaveNoInteractions();
}
@Test
void getContextCustomizerWhenHasTypeMappingShouldReturnCustomizer() {
ContextCustomizer customizer = this.factory.createContextCustomizer(TypeMapping.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(TypeMapping.class, Collections.emptyList());
assertThat(customizer).isNotNull();
}
@Test
void getContextCustomizerWhenHasAttributeMappingShouldReturnCustomizer() {
ContextCustomizer customizer = this.factory.createContextCustomizer(AttributeMapping.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(AttributeMapping.class,
Collections.emptyList());
assertThat(customizer).isNotNull();
}
@Test
void hashCodeAndEqualsShouldBeBasedOnPropertyValues() {
ContextCustomizer customizer1 = this.factory.createContextCustomizer(TypeMapping.class, null);
ContextCustomizer customizer2 = this.factory.createContextCustomizer(AttributeMapping.class, null);
ContextCustomizer customizer3 = this.factory.createContextCustomizer(OtherMapping.class, null);
ContextCustomizer customizer1 = this.factory.createContextCustomizer(TypeMapping.class,
Collections.emptyList());
ContextCustomizer customizer2 = this.factory.createContextCustomizer(AttributeMapping.class,
Collections.emptyList());
ContextCustomizer customizer3 = this.factory.createContextCustomizer(OtherMapping.class,
Collections.emptyList());
assertThat(customizer1).hasSameHashCodeAs(customizer2);
assertThat(customizer1).isEqualTo(customizer1).isEqualTo(customizer2).isNotEqualTo(customizer3);
}
@Test
void prepareContextShouldAddPropertySource() {
ContextCustomizer customizer = this.factory.createContextCustomizer(AttributeMapping.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(AttributeMapping.class,
Collections.emptyList());
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
customizer.customizeContext(context, null);
customizer.customizeContext(context, getMergedConfigConfiguration());
assertThat(context.getEnvironment().getProperty("mapped")).isEqualTo("Mapped");
}
@Test
void propertyMappingShouldNotBeUsedWithComponent() {
ContextCustomizer customizer = this.factory.createContextCustomizer(AttributeMapping.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(AttributeMapping.class,
Collections.emptyList());
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(ConfigMapping.class);
customizer.customizeContext(context, null);
customizer.customizeContext(context, getMergedConfigConfiguration());
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(context::refresh)
.withMessageContaining("The @PropertyMapping annotation "
+ "@PropertyMappingContextCustomizerFactoryTests.TypeMappingAnnotation "
+ "cannot be used in combination with the @Component annotation @Configuration");
}
private MergedContextConfiguration getMergedConfigConfiguration() {
return new MergedContextConfiguration(getClass(), null, null, null, mock(ContextLoader.class));
}
@NoMappingAnnotation
static class NoMapping {
@@ -73,6 +73,7 @@ class SpringBootContextLoaderAotTests {
MergedContextConfiguration mergedConfig = testContextBootstrapper.buildMergedContextConfiguration();
ApplicationContextInitializer<ConfigurableApplicationContext> contextInitializer = aotContextInitializers
.getContextInitializer(testClass);
assertThat(contextInitializer).isNotNull();
ConfigurableApplicationContext context = (ConfigurableApplicationContext) ((AotContextLoader) mergedConfig
.getContextLoader()).loadContextForAotRuntime(mergedConfig, contextInitializer);
assertThat(context).isExactlyInstanceOf(GenericApplicationContext.class);
@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -288,6 +289,7 @@ class SpringBootContextLoaderTests {
TestContext context = new ExposedTestContextManager(testClass).getExposedTestContext();
MergedContextConfiguration config = (MergedContextConfiguration) ReflectionTestUtils.getField(context,
"mergedConfig");
assertThat(config).isNotNull();
return TestPropertySourceUtils.convertInlinedPropertiesToMap(config.getPropertySourceProperties());
}
@@ -494,12 +496,12 @@ class SpringBootContextLoaderTests {
private static final class ContextLoaderApplicationContextFailureProcessor
implements ApplicationContextFailureProcessor {
static ApplicationContext failedContext;
static @Nullable ApplicationContext failedContext;
static Throwable contextLoadException;
static @Nullable Throwable contextLoadException;
@Override
public void processLoadFailure(ApplicationContext context, Throwable exception) {
public void processLoadFailure(ApplicationContext context, @Nullable Throwable exception) {
failedContext = context;
contextLoadException = exception;
}
@@ -16,6 +16,7 @@
package org.springframework.boot.test.context;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
@@ -33,7 +34,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class SpringBootTestCustomConfigNameTests {
@Value("${test.foo}")
private String foo;
private @Nullable String foo;
@Test
void propertyIsLoadedFromConfigFileWithCustomName() {
@@ -67,6 +67,7 @@ class SpringBootTestWithActiveProfilesAndSystemEnvironmentPropertyTests {
ConfigurableEnvironment environment = new StandardEnvironment();
MutablePropertySources sources = environment.getPropertySources();
PropertySource<?> source = sources.get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
assertThat(source).isNotNull();
Map<String, Object> map = new LinkedHashMap<>((Map<String, Object>) source.getSource());
map.put("SPRING_PROFILES_ACTIVE", "local");
sources.replace(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
@@ -16,6 +16,7 @@
package org.springframework.boot.test.context;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -82,22 +83,22 @@ class SpringBootTestWithTestPropertySourceTests {
static class Config {
@Value("${boot-test-inlined}")
private String bootTestInlined;
private @Nullable String bootTestInlined;
@Value("${property-source-inlined}")
private String propertySourceInlined;
private @Nullable String propertySourceInlined;
@Value("${property-source-location}")
private String propertySourceLocation;
private @Nullable String propertySourceLocation;
@Value("${a}")
private String propertySourceInlinedOverridesPropertySourceLocation;
private @Nullable String propertySourceInlinedOverridesPropertySourceLocation;
@Value("${b}")
private String bootTestInlinedOverridesPropertySourceLocation;
private @Nullable String bootTestInlinedOverridesPropertySourceLocation;
@Value("${c}")
private String propertySourceInlinedOverridesBootTestInlined;
private @Nullable String propertySourceInlinedOverridesBootTestInlined;
@Bean
static PropertySourcesPlaceholderConfigurer propertyPlaceholder() {
@@ -43,6 +43,7 @@ import static org.mockito.BDDMockito.then;
class ApplicationContextAssertProviderTests {
@Mock
@SuppressWarnings("NullAway.Init")
private ConfigurableApplicationContext mockContext;
private RuntimeException startupFailure;
@@ -61,6 +62,7 @@ class ApplicationContextAssertProviderTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void getWhenTypeIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(
() -> ApplicationContextAssertProvider.get(null, ApplicationContext.class, this.mockContextSupplier))
@@ -68,6 +70,7 @@ class ApplicationContextAssertProviderTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void getWhenTypeIsClassShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(
() -> ApplicationContextAssertProvider.get(null, ApplicationContext.class, this.mockContextSupplier))
@@ -83,6 +86,7 @@ class ApplicationContextAssertProviderTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void getWhenContextTypeIsClassShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> ApplicationContextAssertProvider.get(TestAssertProviderApplicationContext.class, null,
@@ -60,6 +60,7 @@ class ApplicationContextAssertTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void createWhenApplicationContextIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> new ApplicationContextAssert<>(null, null))
.withMessageContaining("'applicationContext' must not be null");
@@ -80,6 +80,7 @@ class FilterAnnotationsTests {
private FilterAnnotations get(Class<?> type) {
Filters filters = AnnotatedElementUtils.getMergedAnnotation(type, Filters.class);
assertThat(filters).isNotNull();
return new FilterAnnotations(getClass().getClassLoader(), filters.value());
}
@@ -16,6 +16,9 @@
package org.springframework.boot.test.context.filter.annotation;
import java.util.Collections;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.boot.context.TypeExcludeFilter;
@@ -46,35 +49,42 @@ class TypeExcludeFiltersContextCustomizerFactoryTests {
@Test
void getContextCustomizerWhenHasNoAnnotationShouldReturnNull() {
ContextCustomizer customizer = this.factory.createContextCustomizer(NoAnnotation.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(NoAnnotation.class,
Collections.emptyList());
assertThat(customizer).isNull();
}
@Test
void getContextCustomizerWhenHasAnnotationShouldReturnCustomizer() {
ContextCustomizer customizer = this.factory.createContextCustomizer(WithExcludeFilters.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(WithExcludeFilters.class,
Collections.emptyList());
assertThat(customizer).isNotNull();
}
@Test
void getContextCustomizerWhenEnclosingClassHasAnnotationShouldReturnCustomizer() {
ContextCustomizer customizer = this.factory.createContextCustomizer(WithEnclosingClassExcludeFilters.class,
null);
Collections.emptyList());
assertThat(customizer).isNotNull();
}
@Test
void hashCodeAndEquals() {
ContextCustomizer customizer1 = this.factory.createContextCustomizer(WithExcludeFilters.class, null);
ContextCustomizer customizer2 = this.factory.createContextCustomizer(WithSameExcludeFilters.class, null);
ContextCustomizer customizer3 = this.factory.createContextCustomizer(WithDifferentExcludeFilters.class, null);
ContextCustomizer customizer1 = this.factory.createContextCustomizer(WithExcludeFilters.class,
Collections.emptyList());
ContextCustomizer customizer2 = this.factory.createContextCustomizer(WithSameExcludeFilters.class,
Collections.emptyList());
ContextCustomizer customizer3 = this.factory.createContextCustomizer(WithDifferentExcludeFilters.class,
Collections.emptyList());
assertThat(customizer1).hasSameHashCodeAs(customizer2);
assertThat(customizer1).isEqualTo(customizer1).isEqualTo(customizer2).isNotEqualTo(customizer3);
}
@Test
void getContextCustomizerShouldAddExcludeFilters() throws Exception {
ContextCustomizer customizer = this.factory.createContextCustomizer(WithExcludeFilters.class, null);
ContextCustomizer customizer = this.factory.createContextCustomizer(WithExcludeFilters.class,
Collections.emptyList());
assertThat(customizer).isNotNull();
customizer.customizeContext(this.context, this.mergedContextConfiguration);
this.context.refresh();
TypeExcludeFilter filter = this.context.getBean(TypeExcludeFilter.class);
@@ -123,8 +133,8 @@ class TypeExcludeFiltersContextCustomizerFactoryTests {
}
@Override
public boolean equals(Object obj) {
return obj.getClass() == getClass();
public boolean equals(@Nullable Object obj) {
return obj != null && obj.getClass() == getClass();
}
@Override
@@ -66,6 +66,7 @@ class ContextConsumerTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void andThenWithNull() {
ContextConsumer<?> consumer = (context) -> {
};
@@ -62,6 +62,7 @@ class BaseUrlTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void ofWhenUrlIssNull() {
assertThatIllegalArgumentException().isThrownBy(() -> BaseUrl.of(null)).withMessage("'url' must not be null");
}
@@ -77,6 +78,7 @@ class BaseUrlTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void ofWhenResolverIsNull() {
assertThatIllegalArgumentException().isThrownBy(() -> BaseUrl.of(true, null))
.withMessage("'resolver' must not be null");
@@ -29,6 +29,7 @@ import java.util.List;
import java.util.Map;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -90,6 +91,7 @@ abstract class AbstractJsonMarshalTesterTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void createWhenResourceLoadClassIsNullShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> createTester(null, ResolvableType.forClass(ExampleObject.class)))
@@ -97,6 +99,7 @@ abstract class AbstractJsonMarshalTesterTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void createWhenTypeIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> createTester(getClass(), null))
.withMessageContaining("'type' must not be null");
@@ -188,14 +191,15 @@ abstract class AbstractJsonMarshalTesterTests {
*/
static class ResolvableTypes {
public List<ExampleObject> listOfExampleObject;
public @Nullable List<ExampleObject> listOfExampleObject;
public ExampleObject[] arrayOfExampleObject;
public ExampleObject @Nullable [] arrayOfExampleObject;
public Map<String, ExampleObject> mapOfExampleObject;
public @Nullable Map<String, ExampleObject> mapOfExampleObject;
static ResolvableType get(String name) {
Field field = ReflectionUtils.findField(ResolvableTypes.class, name);
assertThat(field).isNotNull();
return ResolvableType.forField(field);
}
@@ -43,6 +43,7 @@ class BasicJsonTesterTests {
private final BasicJsonTester json = new BasicJsonTester(getClass());
@Test
@SuppressWarnings("NullAway") // Test null check
void createWhenResourceLoadClassIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> new BasicJsonTester(null))
.withMessageContaining("'resourceLoadClass' must not be null");
@@ -43,6 +43,7 @@ class DuplicateJsonObjectContextCustomizerFactoryTests {
}
@Test
@SuppressWarnings("NullAway") // Uses null for quick test setup
void warningForMultipleVersions() {
new DuplicateJsonObjectContextCustomizerFactory().createContextCustomizer(null, null)
.customizeContext(null, null);
@@ -16,6 +16,8 @@
package org.springframework.boot.test.json;
import org.jspecify.annotations.Nullable;
import org.springframework.util.ObjectUtils;
/**
@@ -23,15 +25,15 @@ import org.springframework.util.ObjectUtils;
*/
public class ExampleObject {
private String name;
private @Nullable String name;
private int age;
public String getName() {
public @Nullable String getName() {
return this.name;
}
public void setName(String name) {
public void setName(@Nullable String name) {
this.name = name;
}
@@ -17,6 +17,7 @@
package org.springframework.boot.test.json;
import com.fasterxml.jackson.annotation.JsonView;
import org.jspecify.annotations.Nullable;
import org.springframework.util.ObjectUtils;
@@ -28,15 +29,15 @@ import org.springframework.util.ObjectUtils;
public class ExampleObjectWithView {
@JsonView(TestView.class)
private String name;
private @Nullable String name;
private int age;
public String getName() {
public @Nullable String getName() {
return this.name;
}
public void setName(String name) {
public void setName(@Nullable String name) {
this.name = name;
}
@@ -35,12 +35,16 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class GsonTesterIntegrationTests {
@SuppressWarnings("NullAway.Init")
private GsonTester<ExampleObject> simpleJson;
@SuppressWarnings("NullAway.Init")
private GsonTester<List<ExampleObject>> listJson;
@SuppressWarnings("NullAway.Init")
private GsonTester<Map<String, Integer>> mapJson;
@SuppressWarnings("NullAway.Init")
private GsonTester<String> stringJson;
private Gson gson;
@@ -20,6 +20,7 @@ import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.core.ResolvableType;
@@ -35,12 +36,14 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
class GsonTesterTests extends AbstractJsonMarshalTesterTests {
@Test
@SuppressWarnings("NullAway") // Test null check
void initFieldsWhenTestIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> GsonTester.initFields(null, new GsonBuilder().create()))
.withMessageContaining("'testInstance' must not be null");
}
@Test
@SuppressWarnings("NullAway") // Test null check
void initFieldsWhenMarshallerIsNullShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> GsonTester.initFields(new InitFieldsTestClass(), (Gson) null))
@@ -55,8 +58,10 @@ class GsonTesterTests extends AbstractJsonMarshalTesterTests {
GsonTester.initFields(test, new GsonBuilder().create());
assertThat(test.test).isNotNull();
assertThat(test.base).isNotNull();
assertThat(test.test.getType().resolve()).isEqualTo(List.class);
assertThat(test.test.getType().resolveGeneric()).isEqualTo(ExampleObject.class);
ResolvableType type = test.test.getType();
assertThat(type).isNotNull();
assertThat(type.resolve()).isEqualTo(List.class);
assertThat(type.resolveGeneric()).isEqualTo(ExampleObject.class);
}
@Override
@@ -66,7 +71,7 @@ class GsonTesterTests extends AbstractJsonMarshalTesterTests {
abstract static class InitFieldsBaseClass {
public GsonTester<ExampleObject> base;
public @Nullable GsonTester<ExampleObject> base;
public GsonTester<ExampleObject> baseSet = new GsonTester<>(InitFieldsBaseClass.class,
ResolvableType.forClass(ExampleObject.class), new GsonBuilder().create());
@@ -75,7 +80,7 @@ class GsonTesterTests extends AbstractJsonMarshalTesterTests {
static class InitFieldsTestClass extends InitFieldsBaseClass {
public GsonTester<List<ExampleObject>> test;
public @Nullable GsonTester<List<ExampleObject>> test;
public GsonTester<ExampleObject> testSet = new GsonTester<>(InitFieldsBaseClass.class,
ResolvableType.forClass(ExampleObject.class), new GsonBuilder().create());
@@ -40,14 +40,19 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class JacksonTesterIntegrationTests {
@SuppressWarnings("NullAway.Init")
private JacksonTester<ExampleObject> simpleJson;
@SuppressWarnings("NullAway.Init")
private JacksonTester<ExampleObjectWithView> jsonWithView;
@SuppressWarnings("NullAway.Init")
private JacksonTester<List<ExampleObject>> listJson;
@SuppressWarnings("NullAway.Init")
private JacksonTester<Map<String, Integer>> mapJson;
@SuppressWarnings("NullAway.Init")
private JacksonTester<String> stringJson;
private static final String JSON = "{\"name\":\"Spring\",\"age\":123}";
@@ -55,8 +60,7 @@ class JacksonTesterIntegrationTests {
@Test
void typicalTest() throws Exception {
JacksonTester.initFields(this, new JsonMapper());
String example = JSON;
assertThat(this.simpleJson.parse(example).getObject().getName()).isEqualTo("Spring");
assertThat(this.simpleJson.parse(JSON).getObject().getName()).isEqualTo("Spring");
}
@Test
@@ -18,6 +18,7 @@ package org.springframework.boot.test.json;
import java.util.List;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import tools.jackson.databind.json.JsonMapper;
@@ -34,12 +35,14 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
class JacksonTesterTests extends AbstractJsonMarshalTesterTests {
@Test
@SuppressWarnings("NullAway") // Test null check
void initFieldsWhenTestIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> JacksonTester.initFields(null, new JsonMapper()))
.withMessageContaining("'testInstance' must not be null");
}
@Test
@SuppressWarnings("NullAway") // Test null check
void initFieldsWhenMarshallerIsNullShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> JacksonTester.initFields(new InitFieldsTestClass(), (JsonMapper) null))
@@ -54,8 +57,10 @@ class JacksonTesterTests extends AbstractJsonMarshalTesterTests {
JacksonTester.initFields(test, new JsonMapper());
assertThat(test.test).isNotNull();
assertThat(test.base).isNotNull();
assertThat(test.test.getType().resolve()).isEqualTo(List.class);
assertThat(test.test.getType().resolveGeneric()).isEqualTo(ExampleObject.class);
ResolvableType type = test.test.getType();
assertThat(type).isNotNull();
assertThat(type.resolve()).isEqualTo(List.class);
assertThat(type.resolveGeneric()).isEqualTo(ExampleObject.class);
}
@Override
@@ -65,7 +70,7 @@ class JacksonTesterTests extends AbstractJsonMarshalTesterTests {
abstract static class InitFieldsBaseClass {
public JacksonTester<ExampleObject> base;
public @Nullable JacksonTester<ExampleObject> base;
public JacksonTester<ExampleObject> baseSet = new JacksonTester<>(InitFieldsBaseClass.class,
ResolvableType.forClass(ExampleObject.class), new JsonMapper());
@@ -74,7 +79,7 @@ class JacksonTesterTests extends AbstractJsonMarshalTesterTests {
static class InitFieldsTestClass extends InitFieldsBaseClass {
public JacksonTester<List<ExampleObject>> test;
public @Nullable JacksonTester<List<ExampleObject>> test;
public JacksonTester<ExampleObject> testSet = new JacksonTester<>(InitFieldsBaseClass.class,
ResolvableType.forClass(ExampleObject.class), new JsonMapper());
@@ -23,6 +23,7 @@ import java.io.InputStream;
import java.nio.file.Path;
import org.assertj.core.api.AssertProvider;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -63,6 +64,7 @@ class JsonContentAssertTests {
private static final JSONComparator COMPARATOR = new DefaultComparator(JSONCompareMode.LENIENT);
@TempDir
@SuppressWarnings("NullAway.Init")
public Path tempDir;
private File temp;
@@ -1288,7 +1290,7 @@ class JsonContentAssertTests {
}
private AssertProvider<JsonContentAssert> forJson(String json) {
private AssertProvider<JsonContentAssert> forJson(@Nullable String json) {
return () -> new JsonContentAssert(JsonContentAssertTests.class, json);
}
@@ -36,6 +36,7 @@ class JsonContentTests {
private static final ResolvableType TYPE = ResolvableType.forClass(ExampleObject.class);
@Test
@SuppressWarnings("NullAway") // Test null check
void createWhenResourceLoadClassIsNullShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new JsonContent<ExampleObject>(null, TYPE, JSON, Configuration.defaultConfiguration()))
@@ -43,6 +44,7 @@ class JsonContentTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void createWhenJsonIsNullShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(
@@ -51,6 +53,7 @@ class JsonContentTests {
}
@Test
@SuppressWarnings("NullAway") // Test null check
void createWhenConfigurationIsNullShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new JsonContent<ExampleObject>(getClass(), TYPE, JSON, null))
@@ -20,6 +20,7 @@ import java.util.List;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.core.ResolvableType;
@@ -35,12 +36,14 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
class JsonbTesterTests extends AbstractJsonMarshalTesterTests {
@Test
@SuppressWarnings("NullAway") // Test null check
void initFieldsWhenTestIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> JsonbTester.initFields(null, JsonbBuilder.create()))
.withMessageContaining("'testInstance' must not be null");
}
@Test
@SuppressWarnings("NullAway") // Test null check
void initFieldsWhenMarshallerIsNullShouldThrowException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> JsonbTester.initFields(new InitFieldsTestClass(), (Jsonb) null))
@@ -55,8 +58,10 @@ class JsonbTesterTests extends AbstractJsonMarshalTesterTests {
JsonbTester.initFields(test, JsonbBuilder.create());
assertThat(test.test).isNotNull();
assertThat(test.base).isNotNull();
assertThat(test.test.getType().resolve()).isEqualTo(List.class);
assertThat(test.test.getType().resolveGeneric()).isEqualTo(ExampleObject.class);
ResolvableType type = test.test.getType();
assertThat(type).isNotNull();
assertThat(type.resolve()).isEqualTo(List.class);
assertThat(type.resolveGeneric()).isEqualTo(ExampleObject.class);
}
@Override
@@ -66,7 +71,7 @@ class JsonbTesterTests extends AbstractJsonMarshalTesterTests {
abstract static class InitFieldsBaseClass {
public JsonbTester<ExampleObject> base;
public @Nullable JsonbTester<ExampleObject> base;
public JsonbTester<ExampleObject> baseSet = new JsonbTester<>(InitFieldsBaseClass.class,
ResolvableType.forClass(ExampleObject.class), JsonbBuilder.create());
@@ -75,7 +80,7 @@ class JsonbTesterTests extends AbstractJsonMarshalTesterTests {
static class InitFieldsTestClass extends InitFieldsBaseClass {
public JsonbTester<List<ExampleObject>> test;
public @Nullable JsonbTester<List<ExampleObject>> test;
public JsonbTester<ExampleObject> testSet = new JsonbTester<>(InitFieldsBaseClass.class,
ResolvableType.forClass(ExampleObject.class), JsonbBuilder.create());
@@ -35,6 +35,7 @@ class ObjectContentTests {
private static final ResolvableType TYPE = ResolvableType.forClass(ExampleObject.class);
@Test
@SuppressWarnings("NullAway") // Test null check
void createWhenObjectIsNullShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> new ObjectContent<ExampleObject>(TYPE, null))
.withMessageContaining("'object' must not be null");
@@ -47,6 +47,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@WebAppConfiguration("src/test/webapp")
class SpringBootMockServletContextTests implements ServletContextAware {
@SuppressWarnings("NullAway.Init")
private ServletContext servletContext;
@Override
@@ -21,6 +21,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.util.TestPropertyValues.Pair;
@@ -191,8 +192,10 @@ class TestPropertyValuesTests {
@Test
void pairOfCreatesPair() {
Map<String, Object> map = new LinkedHashMap<>();
Pair.of("spring", "boot").addTo(map);
Map<String, @Nullable Object> map = new LinkedHashMap<>();
Pair pair = Pair.of("spring", "boot");
assertThat(pair).isNotNull();
pair.addTo(map);
assertThat(map).containsOnly(entry("spring", "boot"));
}
@@ -203,8 +206,10 @@ class TestPropertyValuesTests {
@Test
void pairFromMapEntryCreatesPair() {
Map<String, Object> map = new LinkedHashMap<>();
Pair.fromMapEntry(entry("spring", "boot")).addTo(map);
Map<String, @Nullable Object> map = new LinkedHashMap<>();
Pair pair = Pair.fromMapEntry(entry("spring", "boot"));
assertThat(pair).isNotNull();
pair.addTo(map);
assertThat(map).containsOnly(entry("spring", "boot"));
}
@@ -16,6 +16,7 @@
package org.springframework.boot.test.web.server;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -36,10 +37,10 @@ import static org.assertj.core.api.Assertions.assertThat;
class LocalManagementPortTests {
@Value("${local.management.port}")
private String fromValue;
private @Nullable String fromValue;
@LocalManagementPort
private String fromAnnotation;
private @Nullable String fromAnnotation;
@Test
void testLocalManagementPortAnnotation() {
@@ -16,6 +16,7 @@
package org.springframework.boot.test.web.server;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -37,10 +38,10 @@ import static org.assertj.core.api.Assertions.assertThat;
class LocalServerPortTests {
@Value("${local.server.port}")
private String fromValue;
private @Nullable String fromValue;
@LocalServerPort
private String fromAnnotation;
private @Nullable String fromAnnotation;
@Test
void testLocalServerPortAnnotation() {