Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QuarkusComponentTest: collect injection points from superclasses #34059

Merged
merged 1 commit into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
QuarkusComponentTest: collect injection points from superclasses
  • Loading branch information
mkouba committed Jun 15, 2023
commit 2bcc5bb44910cc5141292b3cd140dbb2adb7f477
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@

import org.junit.jupiter.api.extension.ExtendWith;

import io.quarkus.test.InjectMock;
import io.smallrye.common.annotation.Experimental;

/**
* Registers the {@link QuarkusComponentTestExtension} that makes it easy to test Quarkus components.
*
* @see InjectMock
* @see TestConfigProperty
*/
@Experimental("This feature is experimental and the API may change in the future")
@ExtendWith(QuarkusComponentTestExtension.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@
* configuration properties via the {@link #configProperty(String, String)} method. If you only need to use the default values
* for missing config properties, then the {@link #useDefaultConfigProperties()}
* might come in useful.
*
* @see InjectMock
* @see TestConfigProperty
*/
@Experimental("This feature is experimental and the API may change in the future")
public class QuarkusComponentTestExtension
Expand Down Expand Up @@ -195,7 +198,7 @@ public QuarkusComponentTestExtension configProperty(String key, String value) {
}

/**
* Use the default values for missing config properties. By default, if missing config property results in a test failure.
* Use the default values for missing config properties. By default, a missing config property results in a test failure.
* <p>
* For primitives the default values as defined in the JLS are used. For any other type {@code null} is injected.
*
Expand Down Expand Up @@ -246,10 +249,14 @@ public void beforeAll(ExtensionContext context) throws Exception {
}
}
// All fields annotated with @Inject represent component classes
for (Field field : testClass.getDeclaredFields()) {
if (field.isAnnotationPresent(Inject.class) && !resolvesToBuiltinBean(field.getType())) {
componentClasses.add(field.getType());
Class<?> current = testClass;
while (current != null) {
for (Field field : current.getDeclaredFields()) {
if (field.isAnnotationPresent(Inject.class) && !resolvesToBuiltinBean(field.getType())) {
componentClasses.add(field.getType());
}
}
current = current.getSuperclass();
}

TestConfigProperty[] testConfigProperties = testClass.getAnnotationsByType(TestConfigProperty.class);
Expand Down Expand Up @@ -761,13 +768,17 @@ private List<FieldInjector> injectFields(Class<?> testClass, Object testInstance
injectAnnotations = List.of(Inject.class, InjectMock.class);
}
List<FieldInjector> injectedFields = new ArrayList<>();
for (Field field : testClass.getDeclaredFields()) {
for (Class<? extends Annotation> annotation : injectAnnotations) {
if (field.isAnnotationPresent(annotation)) {
injectedFields.add(new FieldInjector(field, testInstance));
break;
Class<?> current = testClass;
while (current.getSuperclass() != null) {
for (Field field : current.getDeclaredFields()) {
for (Class<? extends Annotation> annotation : injectAnnotations) {
if (field.isAnnotationPresent(annotation)) {
injectedFields.add(new FieldInjector(field, testInstance));
break;
}
}
}
current = current.getSuperclass();
}
return injectedFields;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import io.quarkus.test.component.TestConfigProperty.TestConfigProperties;

/**
* Set a configuration property for the test.
* Set the value of a configuration property for a {@code io.quarkus.test.component.QuarkusComponentTest}.
*
* @see QuarkusComponentTest
* @see QuarkusComponentTestExtension#configProperty(String, String)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.quarkus.test.component.declarative;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import io.quarkus.test.component.QuarkusComponentTest;
import io.quarkus.test.component.TestConfigProperty;

@QuarkusComponentTest
@TestConfigProperty(key = "foo", value = "BAR")
public class SuperClassInjectionTest extends SuperTest {

@Test
public void testPing() {
Mockito.when(charlie.ping()).thenReturn("foo");
assertEquals("foo and BAR", myComponent.ping());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.quarkus.test.component.declarative;

import jakarta.inject.Inject;

import io.quarkus.test.InjectMock;
import io.quarkus.test.component.beans.Charlie;
import io.quarkus.test.component.beans.MyComponent;

public abstract class SuperTest {

@Inject
MyComponent myComponent;

@InjectMock
Charlie charlie;

}