org.neo4j.test.extension.StatefulFieldExtension Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of test-utils Show documentation
Show all versions of test-utils Show documentation
A set of utilities used by tests.
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.test.extension;
import static java.lang.String.format;
import static org.neo4j.test.ReflectionUtil.getAllFields;
import java.lang.reflect.Field;
import java.util.List;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.ExtensionConfigurationException;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
import org.junit.jupiter.api.extension.ExtensionContext.Store;
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
public abstract class StatefulFieldExtension implements TestInstancePostProcessor, AfterAllCallback {
protected abstract String getFieldKey();
protected abstract Class getFieldType();
protected abstract T createField(ExtensionContext extensionContext);
protected abstract Namespace getNameSpace();
@Override
public void afterAll(ExtensionContext context) throws Exception {
removeStoredValue(context);
}
@Override
public void postProcessTestInstance(Object testInstance, ExtensionContext context) throws Exception {
Class> clazz = testInstance.getClass();
Object instance = createInstance(context);
List declaredFields = getAllFields(clazz);
for (Field declaredField : declaredFields) {
if (declaredField.isAnnotationPresent(Inject.class)
&& declaredField.getType().isAssignableFrom(getFieldType())) {
declaredField.setAccessible(true);
if (declaredField.get(testInstance) != null) {
throw new ExtensionConfigurationException(format(
"Field %s that is marked for injection in class %s is managed by extension container "
+ "and should not have any manually assigned value.",
declaredField.getName(), clazz.getName()));
}
declaredField.set(testInstance, instance);
}
}
}
protected T getStoredValue(ExtensionContext context) {
return getLocalStore(context).get(getFieldKey(), getFieldType());
}
protected T removeStoredValue(ExtensionContext context) {
return getLocalStore(context).remove(getFieldKey(), getFieldType());
}
protected T deepRemoveStoredValue(ExtensionContext context) {
T removedValue = null;
ExtensionContext valueContext = context;
while (removedValue == null && valueContext != null) {
removedValue = removeStoredValue(valueContext);
valueContext = valueContext.getParent().orElse(null);
}
return removedValue;
}
protected static Store getStore(ExtensionContext extensionContext, Namespace namespace) {
return extensionContext.getStore(namespace);
}
protected Store getLocalStore(ExtensionContext extensionContext) {
return getStore(extensionContext, getNameSpace());
}
private Object createInstance(ExtensionContext extensionContext) {
Object value = getStoredValue(extensionContext);
if (value == null) {
value = createField(extensionContext);
getLocalStore(extensionContext).put(getFieldKey(), value);
}
return value;
}
}