TSK-1941: test-api injects enclosing class instance for non-static member classes
this allows SPIs to use instance fields from their enclosing class
This commit is contained in:
parent
41ecfa2245
commit
830723800e
|
|
@ -44,4 +44,18 @@ public class ReflectionUtil {
|
||||||
public static <T> Class<T> wrap(Class<T> c) {
|
public static <T> Class<T> wrap(Class<T> c) {
|
||||||
return c.isPrimitive() ? (Class<T>) PRIMITIVES_TO_WRAPPERS.get(c) : c;
|
return c.isPrimitive() ? (Class<T>) PRIMITIVES_TO_WRAPPERS.get(c) : c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Object getEnclosingInstance(Object instance) {
|
||||||
|
return Arrays.stream(instance.getClass().getDeclaredFields())
|
||||||
|
.filter(Field::isSynthetic)
|
||||||
|
.filter(f -> f.getName().startsWith("this"))
|
||||||
|
.findFirst()
|
||||||
|
.map(
|
||||||
|
CheckedFunction.wrap(
|
||||||
|
field -> {
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(instance);
|
||||||
|
}))
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ import java.lang.reflect.Field;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import pro.taskana.common.internal.util.TopLevelTestClass.FirstNestedClass;
|
||||||
|
import pro.taskana.common.internal.util.TopLevelTestClass.FirstNestedClass.SecondNestedClass;
|
||||||
|
|
||||||
class ReflectionUtilTest {
|
class ReflectionUtilTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -31,6 +34,36 @@ class ReflectionUtilTest {
|
||||||
assertThat(wrap).isEqualTo(TestClass.class);
|
assertThat(wrap).isEqualTo(TestClass.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_ReturnNull_For_TopLevelClass() {
|
||||||
|
TopLevelTestClass topLevelTestClass = new TopLevelTestClass();
|
||||||
|
|
||||||
|
Object enclosingInstance = ReflectionUtil.getEnclosingInstance(topLevelTestClass);
|
||||||
|
|
||||||
|
assertThat(enclosingInstance).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_ReturnTopLevelInstance_For_NestedInstance() {
|
||||||
|
TopLevelTestClass topLevelTestClass = new TopLevelTestClass();
|
||||||
|
FirstNestedClass firstNestedClass = topLevelTestClass.new FirstNestedClass();
|
||||||
|
|
||||||
|
Object enclosingInstance = ReflectionUtil.getEnclosingInstance(firstNestedClass);
|
||||||
|
|
||||||
|
assertThat(enclosingInstance).isSameAs(topLevelTestClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_ReturnNestedInstance_For_NestedNestedInstance() {
|
||||||
|
TopLevelTestClass topLevelTestClass = new TopLevelTestClass();
|
||||||
|
FirstNestedClass firstNestedClass = topLevelTestClass.new FirstNestedClass();
|
||||||
|
SecondNestedClass secondNestedClass = firstNestedClass.new SecondNestedClass();
|
||||||
|
|
||||||
|
Object enclosingInstance = ReflectionUtil.getEnclosingInstance(secondNestedClass);
|
||||||
|
|
||||||
|
assertThat(enclosingInstance).isSameAs(firstNestedClass);
|
||||||
|
}
|
||||||
|
|
||||||
static class TestClass {
|
static class TestClass {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
String fieldA;
|
String fieldA;
|
||||||
|
|
@ -46,3 +79,16 @@ class ReflectionUtilTest {
|
||||||
String fieldC;
|
String fieldC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"checkstyle:OneTopLevelClass", "InnerClassMayBeStatic", "unused"})
|
||||||
|
class TopLevelTestClass {
|
||||||
|
String someField;
|
||||||
|
|
||||||
|
class FirstNestedClass {
|
||||||
|
String someField;
|
||||||
|
|
||||||
|
class SecondNestedClass {
|
||||||
|
String someField;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,6 @@ class TaskRoutingAccTest {
|
||||||
.permission(WorkbasketPermission.READ)
|
.permission(WorkbasketPermission.READ)
|
||||||
.permission(WorkbasketPermission.APPEND)
|
.permission(WorkbasketPermission.APPEND)
|
||||||
.buildAndStore(workbasketService);
|
.buildAndStore(workbasketService);
|
||||||
|
|
||||||
TaskRoutingProviderForDomainA.domainAWorkbasketId = domainAWorkbasket.getId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@WithAccessId(user = "user-1-1")
|
@WithAccessId(user = "user-1-1")
|
||||||
|
|
@ -83,9 +81,7 @@ class TaskRoutingAccTest {
|
||||||
assertThat(createdTask.getWorkbasketSummary()).isEqualTo(domainAWorkbasket);
|
assertThat(createdTask.getWorkbasketSummary()).isEqualTo(domainAWorkbasket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TaskRoutingProviderForDomainA implements TaskRoutingProvider {
|
class TaskRoutingProviderForDomainA implements TaskRoutingProvider {
|
||||||
|
|
||||||
static String domainAWorkbasketId;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(TaskanaEngine taskanaEngine) {}
|
public void initialize(TaskanaEngine taskanaEngine) {}
|
||||||
|
|
@ -93,7 +89,7 @@ class TaskRoutingAccTest {
|
||||||
@Override
|
@Override
|
||||||
public String determineWorkbasketId(Task task) {
|
public String determineWorkbasketId(Task task) {
|
||||||
if ("DOMAIN_A".equals(task.getDomain())) {
|
if ("DOMAIN_A".equals(task.getDomain())) {
|
||||||
return domainAWorkbasketId;
|
return domainAWorkbasket.getId();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import static org.junit.platform.commons.support.AnnotationSupport.isAnnotated;
|
||||||
import static pro.taskana.testapi.util.ExtensionCommunicator.getClassLevelStore;
|
import static pro.taskana.testapi.util.ExtensionCommunicator.getClassLevelStore;
|
||||||
import static pro.taskana.testapi.util.ExtensionCommunicator.isTopLevelClass;
|
import static pro.taskana.testapi.util.ExtensionCommunicator.isTopLevelClass;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import org.apache.ibatis.session.SqlSession;
|
import org.apache.ibatis.session.SqlSession;
|
||||||
|
|
@ -29,6 +30,7 @@ import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||||
import pro.taskana.common.internal.JobServiceImpl;
|
import pro.taskana.common.internal.JobServiceImpl;
|
||||||
import pro.taskana.common.internal.TaskanaEngineImpl;
|
import pro.taskana.common.internal.TaskanaEngineImpl;
|
||||||
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
||||||
|
import pro.taskana.common.internal.util.ReflectionUtil;
|
||||||
import pro.taskana.common.internal.util.SpiLoader;
|
import pro.taskana.common.internal.util.SpiLoader;
|
||||||
import pro.taskana.monitor.api.MonitorService;
|
import pro.taskana.monitor.api.MonitorService;
|
||||||
import pro.taskana.monitor.internal.MonitorServiceImpl;
|
import pro.taskana.monitor.internal.MonitorServiceImpl;
|
||||||
|
|
@ -68,7 +70,8 @@ public class TaskanaInitializationExtension implements TestInstancePostProcessor
|
||||||
|
|
||||||
TaskanaEngine taskanaEngine;
|
TaskanaEngine taskanaEngine;
|
||||||
try (MockedStatic<SpiLoader> staticMock = Mockito.mockStatic(SpiLoader.class)) {
|
try (MockedStatic<SpiLoader> staticMock = Mockito.mockStatic(SpiLoader.class)) {
|
||||||
ServiceProviderExtractor.extractServiceProviders(testClass)
|
ServiceProviderExtractor.extractServiceProviders(
|
||||||
|
testClass, extractEnclosingTestInstances(testInstance))
|
||||||
.forEach(
|
.forEach(
|
||||||
(spi, serviceProviders) ->
|
(spi, serviceProviders) ->
|
||||||
staticMock.when(() -> SpiLoader.load(spi)).thenReturn(serviceProviders));
|
staticMock.when(() -> SpiLoader.load(spi)).thenReturn(serviceProviders));
|
||||||
|
|
@ -80,6 +83,15 @@ public class TaskanaInitializationExtension implements TestInstancePostProcessor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<Class<?>, Object> extractEnclosingTestInstances(Object instance) {
|
||||||
|
HashMap<Class<?>, Object> instanceByClass = new HashMap<>();
|
||||||
|
while (instance != null) {
|
||||||
|
instanceByClass.put(instance.getClass(), instance);
|
||||||
|
instance = ReflectionUtil.getEnclosingInstance(instance);
|
||||||
|
}
|
||||||
|
return instanceByClass;
|
||||||
|
}
|
||||||
|
|
||||||
private static TaskanaEngineConfiguration createDefaultTaskanaEngineConfiguration(Store store) {
|
private static TaskanaEngineConfiguration createDefaultTaskanaEngineConfiguration(Store store) {
|
||||||
String schemaName = store.get(TestContainerExtension.STORE_SCHEMA_NAME, String.class);
|
String schemaName = store.get(TestContainerExtension.STORE_SCHEMA_NAME, String.class);
|
||||||
if (schemaName == null) {
|
if (schemaName == null) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
package pro.taskana.testapi.util;
|
package pro.taskana.testapi.util;
|
||||||
|
|
||||||
import static org.junit.platform.commons.support.AnnotationSupport.findRepeatableAnnotations;
|
import static org.junit.platform.commons.support.AnnotationSupport.findRepeatableAnnotations;
|
||||||
import static pro.taskana.common.internal.util.CheckedFunction.wrap;
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -12,6 +10,7 @@ import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.junit.platform.commons.JUnitException;
|
import org.junit.platform.commons.JUnitException;
|
||||||
|
import org.junit.platform.commons.support.ReflectionSupport;
|
||||||
|
|
||||||
import pro.taskana.spi.history.api.TaskanaHistory;
|
import pro.taskana.spi.history.api.TaskanaHistory;
|
||||||
import pro.taskana.spi.priority.api.PriorityServiceProvider;
|
import pro.taskana.spi.priority.api.PriorityServiceProvider;
|
||||||
|
|
@ -36,7 +35,8 @@ public class ServiceProviderExtractor {
|
||||||
throw new IllegalStateException("utility class");
|
throw new IllegalStateException("utility class");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<Class<?>, List<Object>> extractServiceProviders(Class<?> testClass) {
|
public static Map<Class<?>, List<Object>> extractServiceProviders(
|
||||||
|
Class<?> testClass, Map<Class<?>, Object> enclosingTestInstancesByClass) {
|
||||||
List<WithServiceProvider> withServiceProviders =
|
List<WithServiceProvider> withServiceProviders =
|
||||||
findRepeatableAnnotations(testClass, WithServiceProvider.class);
|
findRepeatableAnnotations(testClass, WithServiceProvider.class);
|
||||||
|
|
||||||
|
|
@ -44,7 +44,9 @@ public class ServiceProviderExtractor {
|
||||||
.peek(entry -> validateServiceProviders(entry.getKey(), entry.getValue()))
|
.peek(entry -> validateServiceProviders(entry.getKey(), entry.getValue()))
|
||||||
.collect(
|
.collect(
|
||||||
Collectors.toMap(
|
Collectors.toMap(
|
||||||
Entry::getKey, entry -> instantiateServiceProviders(entry.getValue())));
|
Entry::getKey,
|
||||||
|
entry ->
|
||||||
|
instantiateServiceProviders(entry.getValue(), enclosingTestInstancesByClass)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void validateServiceProviders(Class<?> spi, List<Class<?>> serviceProviders) {
|
private static void validateServiceProviders(Class<?> spi, List<Class<?>> serviceProviders) {
|
||||||
|
|
@ -69,24 +71,33 @@ public class ServiceProviderExtractor {
|
||||||
Collectors.toList())));
|
Collectors.toList())));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Object> instantiateServiceProviders(List<Class<?>> serviceProviders) {
|
private static List<Object> instantiateServiceProviders(
|
||||||
|
List<Class<?>> serviceProviders, Map<Class<?>, Object> enclosingTestInstancesByClass) {
|
||||||
return serviceProviders.stream()
|
return serviceProviders.stream()
|
||||||
.map(wrap(ServiceProviderExtractor::instantiateClass))
|
.map(clz -> instantiateClass(clz, enclosingTestInstancesByClass))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object instantiateClass(Class<?> clz) throws Exception {
|
private static Object instantiateClass(
|
||||||
|
Class<?> clz, Map<Class<?>, Object> enclosingTestInstancesByClass) {
|
||||||
// we don't have to consider anonymous classes since they can't be passed as an argument to
|
// we don't have to consider anonymous classes since they can't be passed as an argument to
|
||||||
// the WithServiceProvider annotation.
|
// the WithServiceProvider annotation.
|
||||||
if (clz.isLocalClass() || (clz.isMemberClass() && !Modifier.isStatic(clz.getModifiers()))) {
|
if (clz.isLocalClass() || (clz.isMemberClass() && !Modifier.isStatic(clz.getModifiers()))) {
|
||||||
|
try {
|
||||||
Class<?> motherClass = clz.getEnclosingClass();
|
Class<?> motherClass = clz.getEnclosingClass();
|
||||||
Object motherInstance = instantiateClass(motherClass);
|
Object motherInstance =
|
||||||
Constructor<?> constructor = clz.getDeclaredConstructor(motherClass);
|
enclosingTestInstancesByClass.getOrDefault(
|
||||||
constructor.setAccessible(true);
|
motherClass, instantiateClass(motherClass, enclosingTestInstancesByClass));
|
||||||
return constructor.newInstance(motherInstance);
|
return ReflectionSupport.newInstance(clz, motherInstance);
|
||||||
|
} catch (Exception e) {
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
if (NoSuchMethodException.class == e.getClass()) {
|
||||||
|
throw new JUnitException(
|
||||||
|
"test-api does not support local class which accesses method variables");
|
||||||
}
|
}
|
||||||
Constructor<?> constructor = clz.getDeclaredConstructor();
|
throw e;
|
||||||
constructor.setAccessible(true);
|
}
|
||||||
return constructor.newInstance();
|
}
|
||||||
|
return ReflectionSupport.newInstance(clz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package pro.taskana.testapi.util;
|
package pro.taskana.testapi.util;
|
||||||
|
|
||||||
|
import static java.util.Map.entry;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
import static pro.taskana.testapi.util.ServiceProviderExtractor.extractServiceProviders;
|
import static pro.taskana.testapi.util.ServiceProviderExtractor.extractServiceProviders;
|
||||||
|
|
@ -14,6 +15,7 @@ import org.junit.jupiter.api.TestInstance;
|
||||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||||
import org.junit.platform.commons.JUnitException;
|
import org.junit.platform.commons.JUnitException;
|
||||||
|
|
||||||
|
import pro.taskana.common.internal.util.ReflectionUtil;
|
||||||
import pro.taskana.spi.priority.api.PriorityServiceProvider;
|
import pro.taskana.spi.priority.api.PriorityServiceProvider;
|
||||||
import pro.taskana.spi.task.api.CreateTaskPreprocessor;
|
import pro.taskana.spi.task.api.CreateTaskPreprocessor;
|
||||||
import pro.taskana.task.api.models.Task;
|
import pro.taskana.task.api.models.Task;
|
||||||
|
|
@ -66,16 +68,30 @@ class ServiceProviderExtractorTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("InnerClassMayBeStatic")
|
||||||
|
class NonStaticCreateTaskPreprocessorOutsideOfTestClass implements CreateTaskPreprocessor {
|
||||||
|
@Override
|
||||||
|
public void processTaskBeforeCreation(Task taskToProcess) {
|
||||||
|
// implementation not important for the tests
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestInstance(Lifecycle.PER_CLASS)
|
@TestInstance(Lifecycle.PER_CLASS)
|
||||||
class ServiceProviderInstantiation {
|
class ServiceProviderInstantiation {
|
||||||
|
|
||||||
|
private final Map<Class<?>, Object> enclosingTestInstancesByClass =
|
||||||
|
Map.ofEntries(
|
||||||
|
entry(ServiceProviderInstantiation.class, this),
|
||||||
|
entry(ServiceProviderExtractorTest.class, ServiceProviderExtractorTest.this));
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void should_ReturnEmptyMap_When_NoServiceProviderIsDefined() {
|
void should_ReturnEmptyMap_When_NoServiceProviderIsDefined() {
|
||||||
class ExampleClazzWithNoServiceProviders {}
|
class ExampleTestClassWithNoServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClazzWithNoServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithNoServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).isEmpty();
|
assertThat(extractServiceProviders).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
@ -85,16 +101,17 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = TopLevelCreateTaskPreprocessor.class)
|
serviceProviders = TopLevelCreateTaskPreprocessor.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(TopLevelCreateTaskPreprocessor.class)
|
||||||
.asList()
|
.extracting(ReflectionUtil::getEnclosingInstance)
|
||||||
.containsExactly(TopLevelCreateTaskPreprocessor.class);
|
.containsOnlyNulls();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -102,16 +119,17 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = StaticCreateTaskPreprocessor.class)
|
serviceProviders = StaticCreateTaskPreprocessor.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(StaticCreateTaskPreprocessor.class)
|
||||||
.asList()
|
.extracting(ReflectionUtil::getEnclosingInstance)
|
||||||
.containsExactly(StaticCreateTaskPreprocessor.class);
|
.containsOnlyNulls();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -119,16 +137,17 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = PrivateStaticCreateTaskPreprocessor.class)
|
serviceProviders = PrivateStaticCreateTaskPreprocessor.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(PrivateStaticCreateTaskPreprocessor.class)
|
||||||
.asList()
|
.extracting(ReflectionUtil::getEnclosingInstance)
|
||||||
.containsExactly(PrivateStaticCreateTaskPreprocessor.class);
|
.containsOnlyNulls();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -143,33 +162,35 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = LocalCreateTaskPreprocessor.class)
|
serviceProviders = LocalCreateTaskPreprocessor.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(LocalCreateTaskPreprocessor.class)
|
||||||
.asList()
|
.extracting(ReflectionUtil::getEnclosingInstance)
|
||||||
.containsExactly(LocalCreateTaskPreprocessor.class);
|
.containsExactly(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void should_InstantiateServiceProvider_When_ServiceProviderIsNonStaticMemberClass() {
|
void should_InstantiateServiceProvider_When_ServiceProviderIsNonStaticMemberClass() {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = NonStaticCreateTaskPreprocessor.class)
|
serviceProviders = NonStaticCreateTaskPreprocessorInsideOfTestClass.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(NonStaticCreateTaskPreprocessorInsideOfTestClass.class)
|
||||||
.asList()
|
.extracting(ReflectionUtil::getEnclosingInstance)
|
||||||
.containsExactly(NonStaticCreateTaskPreprocessor.class);
|
.containsExactly(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -177,20 +198,38 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = PrivateNonStaticCreateTaskPreprocessor.class)
|
serviceProviders = PrivateNonStaticCreateTaskPreprocessor.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(PrivateNonStaticCreateTaskPreprocessor.class)
|
||||||
.asList()
|
.extracting(ReflectionUtil::getEnclosingInstance)
|
||||||
.containsExactly(PrivateNonStaticCreateTaskPreprocessor.class);
|
.containsExactly(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
class NonStaticCreateTaskPreprocessor implements CreateTaskPreprocessor {
|
@Test
|
||||||
|
void should_InstantiateServiceProvider_When_ItIsNonStaticMemberClassOutsideOfTestClass() {
|
||||||
|
@WithServiceProvider(
|
||||||
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
|
serviceProviders = NonStaticCreateTaskPreprocessorOutsideOfTestClass.class)
|
||||||
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
|
.hasExactlyElementsOfTypes(NonStaticCreateTaskPreprocessorOutsideOfTestClass.class)
|
||||||
|
.extracting(ReflectionUtil::getEnclosingInstance)
|
||||||
|
.containsExactly(ServiceProviderExtractorTest.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class NonStaticCreateTaskPreprocessorInsideOfTestClass implements CreateTaskPreprocessor {
|
||||||
@Override
|
@Override
|
||||||
public void processTaskBeforeCreation(Task taskToProcess) {
|
public void processTaskBeforeCreation(Task taskToProcess) {
|
||||||
// implementation not important for the tests
|
// implementation not important for the tests
|
||||||
|
|
@ -210,21 +249,26 @@ class ServiceProviderExtractorTest {
|
||||||
@TestInstance(Lifecycle.PER_CLASS)
|
@TestInstance(Lifecycle.PER_CLASS)
|
||||||
class ExtractServiceProvidersFromSingleServiceProviderInterface {
|
class ExtractServiceProvidersFromSingleServiceProviderInterface {
|
||||||
|
|
||||||
|
private final Map<Class<?>, Object> enclosingTestInstancesByClass =
|
||||||
|
Map.ofEntries(
|
||||||
|
entry(ExtractServiceProvidersFromSingleServiceProviderInterface.class, this),
|
||||||
|
entry(ServiceProviderExtractorTest.class, ServiceProviderExtractorTest.this));
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void should_ExtractServiceProvider() {
|
void should_ExtractServiceProvider() {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = DummyTaskPreprocessor1.class)
|
serviceProviders = DummyTaskPreprocessor1.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
|
||||||
.asList()
|
.asList()
|
||||||
.containsExactly(DummyTaskPreprocessor1.class);
|
.hasExactlyElementsOfTypes(DummyTaskPreprocessor1.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -232,16 +276,16 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = {DummyTaskPreprocessor1.class, DummyTaskPreprocessor2.class})
|
serviceProviders = {DummyTaskPreprocessor1.class, DummyTaskPreprocessor2.class})
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
|
||||||
.asList()
|
.asList()
|
||||||
.containsExactly(DummyTaskPreprocessor1.class, DummyTaskPreprocessor2.class);
|
.hasExactlyElementsOfTypes(DummyTaskPreprocessor1.class, DummyTaskPreprocessor2.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -252,16 +296,15 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = DummyTaskPreprocessor2.class)
|
serviceProviders = DummyTaskPreprocessor2.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(DummyTaskPreprocessor1.class, DummyTaskPreprocessor2.class);
|
||||||
.asList()
|
|
||||||
.containsExactly(DummyTaskPreprocessor1.class, DummyTaskPreprocessor2.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -269,16 +312,15 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = {DummyTaskPreprocessor1.class, DummyTaskPreprocessor1.class})
|
serviceProviders = {DummyTaskPreprocessor1.class, DummyTaskPreprocessor1.class})
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
assertThat(extractServiceProviders).containsOnlyKeys(CreateTaskPreprocessor.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(DummyTaskPreprocessor1.class, DummyTaskPreprocessor1.class);
|
||||||
.asList()
|
|
||||||
.containsExactly(DummyTaskPreprocessor1.class, DummyTaskPreprocessor1.class);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -286,6 +328,11 @@ class ServiceProviderExtractorTest {
|
||||||
@TestInstance(Lifecycle.PER_CLASS)
|
@TestInstance(Lifecycle.PER_CLASS)
|
||||||
class ExtractMultipleServiceProvidersFromMultipleServiceProviderInterfaces {
|
class ExtractMultipleServiceProvidersFromMultipleServiceProviderInterfaces {
|
||||||
|
|
||||||
|
private final Map<Class<?>, Object> enclosingTestInstancesByClass =
|
||||||
|
Map.ofEntries(
|
||||||
|
entry(ExtractMultipleServiceProvidersFromMultipleServiceProviderInterfaces.class, this),
|
||||||
|
entry(ServiceProviderExtractorTest.class, ServiceProviderExtractorTest.this));
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void should_ExtractServiceProviders() {
|
void should_ExtractServiceProviders() {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
|
|
@ -294,21 +341,18 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = PriorityServiceProvider.class,
|
serviceProviderInterface = PriorityServiceProvider.class,
|
||||||
serviceProviders = DummyPriorityServiceProvider1.class)
|
serviceProviders = DummyPriorityServiceProvider1.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders)
|
assertThat(extractServiceProviders)
|
||||||
.containsOnlyKeys(CreateTaskPreprocessor.class, PriorityServiceProvider.class);
|
.containsOnlyKeys(CreateTaskPreprocessor.class, PriorityServiceProvider.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(DummyTaskPreprocessor1.class);
|
||||||
.asList()
|
|
||||||
.containsExactly(DummyTaskPreprocessor1.class);
|
|
||||||
assertThat(extractServiceProviders.get(PriorityServiceProvider.class))
|
assertThat(extractServiceProviders.get(PriorityServiceProvider.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(DummyPriorityServiceProvider1.class);
|
||||||
.asList()
|
|
||||||
.containsExactly(DummyPriorityServiceProvider1.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -322,21 +366,18 @@ class ServiceProviderExtractorTest {
|
||||||
DummyPriorityServiceProvider1.class,
|
DummyPriorityServiceProvider1.class,
|
||||||
DummyPriorityServiceProvider2.class
|
DummyPriorityServiceProvider2.class
|
||||||
})
|
})
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
Map<Class<?>, List<Object>> extractServiceProviders =
|
Map<Class<?>, List<Object>> extractServiceProviders =
|
||||||
extractServiceProviders(ExampleClassWithServiceProviders.class);
|
extractServiceProviders(
|
||||||
|
ExampleTestClassWithServiceProviders.class, enclosingTestInstancesByClass);
|
||||||
|
|
||||||
assertThat(extractServiceProviders)
|
assertThat(extractServiceProviders)
|
||||||
.containsOnlyKeys(CreateTaskPreprocessor.class, PriorityServiceProvider.class);
|
.containsOnlyKeys(CreateTaskPreprocessor.class, PriorityServiceProvider.class);
|
||||||
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
assertThat(extractServiceProviders.get(CreateTaskPreprocessor.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(DummyTaskPreprocessor1.class, DummyTaskPreprocessor2.class);
|
||||||
.asList()
|
|
||||||
.containsExactly(DummyTaskPreprocessor1.class, DummyTaskPreprocessor2.class);
|
|
||||||
assertThat(extractServiceProviders.get(PriorityServiceProvider.class))
|
assertThat(extractServiceProviders.get(PriorityServiceProvider.class))
|
||||||
.extracting(Object::getClass)
|
.hasExactlyElementsOfTypes(
|
||||||
.asList()
|
|
||||||
.containsExactly(
|
|
||||||
DummyPriorityServiceProvider1.class, DummyPriorityServiceProvider2.class);
|
DummyPriorityServiceProvider1.class, DummyPriorityServiceProvider2.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -350,9 +391,10 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = ErrorHandling.class,
|
serviceProviderInterface = ErrorHandling.class,
|
||||||
serviceProviders = DummyTaskPreprocessor1.class)
|
serviceProviders = DummyTaskPreprocessor1.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
ThrowingCallable call = () -> extractServiceProviders(ExampleClassWithServiceProviders.class);
|
ThrowingCallable call =
|
||||||
|
() -> extractServiceProviders(ExampleTestClassWithServiceProviders.class, Map.of());
|
||||||
|
|
||||||
assertThatThrownBy(call)
|
assertThatThrownBy(call)
|
||||||
.isInstanceOf(JUnitException.class)
|
.isInstanceOf(JUnitException.class)
|
||||||
|
|
@ -364,9 +406,10 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = DummyPriorityServiceProvider1.class)
|
serviceProviders = DummyPriorityServiceProvider1.class)
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
ThrowingCallable call = () -> extractServiceProviders(ExampleClassWithServiceProviders.class);
|
ThrowingCallable call =
|
||||||
|
() -> extractServiceProviders(ExampleTestClassWithServiceProviders.class, Map.of());
|
||||||
|
|
||||||
assertThatThrownBy(call)
|
assertThatThrownBy(call)
|
||||||
.isInstanceOf(JUnitException.class)
|
.isInstanceOf(JUnitException.class)
|
||||||
|
|
@ -380,9 +423,10 @@ class ServiceProviderExtractorTest {
|
||||||
@WithServiceProvider(
|
@WithServiceProvider(
|
||||||
serviceProviderInterface = CreateTaskPreprocessor.class,
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
serviceProviders = {DummyTaskPreprocessor1.class, DummyPriorityServiceProvider1.class})
|
serviceProviders = {DummyTaskPreprocessor1.class, DummyPriorityServiceProvider1.class})
|
||||||
class ExampleClassWithServiceProviders {}
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
ThrowingCallable call = () -> extractServiceProviders(ExampleClassWithServiceProviders.class);
|
ThrowingCallable call =
|
||||||
|
() -> extractServiceProviders(ExampleTestClassWithServiceProviders.class, Map.of());
|
||||||
|
|
||||||
assertThatThrownBy(call)
|
assertThatThrownBy(call)
|
||||||
.isInstanceOf(JUnitException.class)
|
.isInstanceOf(JUnitException.class)
|
||||||
|
|
@ -390,5 +434,29 @@ class ServiceProviderExtractorTest {
|
||||||
"At least one ServiceProvider does not implement the requested SPI '%s'",
|
"At least one ServiceProvider does not implement the requested SPI '%s'",
|
||||||
CreateTaskPreprocessor.class);
|
CreateTaskPreprocessor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_ThrowException_When_LocalServiceProviderUsesAMethodVariable() {
|
||||||
|
String methodVariable = "foobar";
|
||||||
|
class LocalCreateTaskPreprocessor implements CreateTaskPreprocessor {
|
||||||
|
@Override
|
||||||
|
public void processTaskBeforeCreation(Task taskToProcess) {
|
||||||
|
// implementation not important for the tests
|
||||||
|
taskToProcess.setOwner(methodVariable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@WithServiceProvider(
|
||||||
|
serviceProviderInterface = CreateTaskPreprocessor.class,
|
||||||
|
serviceProviders = LocalCreateTaskPreprocessor.class)
|
||||||
|
class ExampleTestClassWithServiceProviders {}
|
||||||
|
|
||||||
|
ThrowingCallable call =
|
||||||
|
() -> extractServiceProviders(ExampleTestClassWithServiceProviders.class, Map.of());
|
||||||
|
|
||||||
|
assertThatThrownBy(call)
|
||||||
|
.isInstanceOf(JUnitException.class)
|
||||||
|
.hasMessage("test-api does not support local class which accesses method variables");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue