From d8d6cb732329dabae6a0e06e080c5ff708e4e120 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 28 Mar 2023 10:44:17 +0100 Subject: [PATCH] Improve diagnostics with @ServiceConnection on non-static field Closes gh-34795 --- ...ServiceConnectionContextCustomizerFactory.java | 4 ++++ ...ceConnectionContextCustomizerFactoryTests.java | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/service/connection/ServiceConnectionContextCustomizerFactory.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/service/connection/ServiceConnectionContextCustomizerFactory.java index 425b1929ca1..45b3f085d33 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/service/connection/ServiceConnectionContextCustomizerFactory.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/service/connection/ServiceConnectionContextCustomizerFactory.java @@ -17,6 +17,7 @@ package org.springframework.boot.test.autoconfigure.service.connection; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; @@ -62,6 +63,9 @@ class ServiceConnectionContextCustomizerFactory implements ContextCustomizerFact private ContainerConnectionSource createSource(Field field, MergedAnnotation annotation) { + if (!Modifier.isStatic(field.getModifiers())) { + throw new IllegalStateException("@ServiceConnection field '%s' must be static".formatted(field.getName())); + } Class connectionDetailsType = getConnectionDetailsType(annotation); Object fieldValue = getFieldValue(field); Assert.isInstanceOf(GenericContainer.class, fieldValue, diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/service/connection/ServiceConnectionContextCustomizerFactoryTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/service/connection/ServiceConnectionContextCustomizerFactoryTests.java index e5980710cda..1bd04096317 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/service/connection/ServiceConnectionContextCustomizerFactoryTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/service/connection/ServiceConnectionContextCustomizerFactoryTests.java @@ -24,6 +24,7 @@ import org.springframework.boot.autoconfigure.service.connection.ConnectionDetai import org.springframework.boot.test.autoconfigure.service.connection.ServiceConnectionContextCustomizerFactoryTests.ServiceConnections.NestedClass; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; /** * Tests for {@link ServiceConnectionContextCustomizerFactory}. @@ -55,6 +56,13 @@ public class ServiceConnectionContextCustomizerFactoryTests { assertThat(customizer.getSources()).hasSize(3); } + @Test + void whenClassHasNonStaticServiceConnectionThenCreateShouldFailWithHelpfulIllegalStateException() { + assertThatIllegalStateException() + .isThrownBy(() -> this.factory.createContextCustomizer(NonStaticServiceConnection.class, null)) + .withMessage("@ServiceConnection field 'service' must be static"); + } + static class NoServiceConnections { } @@ -77,6 +85,13 @@ public class ServiceConnectionContextCustomizerFactoryTests { } + static class NonStaticServiceConnection { + + @ServiceConnection(TestConnectionDetails.class) + private GenericContainer service = new GenericContainer<>("example"); + + } + static class TestConnectionDetails implements ConnectionDetails { }