Skip to content

Commit fc79000

Browse files
committed
Allow beans to be injected in tests even if they aren't used in the app
Fixes: #1749
1 parent d63d2a1 commit fc79000

File tree

7 files changed

+123
-3
lines changed

7 files changed

+123
-3
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.quarkus.deployment.test;
2+
3+
import org.jboss.builder.BuildStep;
4+
import org.jboss.builder.item.BuildItem;
5+
import org.jboss.jandex.DotName;
6+
7+
// this is only needed because the test modules do not depend on Arc
8+
public interface TestDefiningAnnotationBuildItemProvider {
9+
10+
Output customize(DotName dotName);
11+
12+
class Output {
13+
private final BuildStep buildStep;
14+
private final Class<? extends BuildItem> producer;
15+
16+
public Output(BuildStep buildStep, Class<? extends BuildItem> producer) {
17+
this.buildStep = buildStep;
18+
this.producer = producer;
19+
}
20+
21+
public BuildStep getBuildStep() {
22+
return buildStep;
23+
}
24+
25+
public Class<? extends BuildItem> getProduces() {
26+
return producer;
27+
}
28+
}
29+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.quarkus.arc.deployment.test;
2+
3+
import org.jboss.builder.BuildContext;
4+
import org.jboss.builder.BuildStep;
5+
import org.jboss.jandex.DotName;
6+
7+
import io.quarkus.arc.deployment.BeanDefiningAnnotationBuildItem;
8+
import io.quarkus.deployment.test.TestDefiningAnnotationBuildItemProvider;
9+
10+
public class ArcTestDefiningAnnotationBuildItemProvider implements TestDefiningAnnotationBuildItemProvider {
11+
12+
@Override
13+
public Output customize(DotName dotName) {
14+
return new Output(
15+
new BuildStep() {
16+
@Override
17+
public void execute(BuildContext context) {
18+
context.produce(new BeanDefiningAnnotationBuildItem(dotName));
19+
}
20+
},
21+
BeanDefiningAnnotationBuildItem.class);
22+
}
23+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
io.quarkus.arc.deployment.test.ArcTestDefiningAnnotationBuildItemProvider
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.quarkus.example.arc;
2+
3+
import javax.enterprise.context.ApplicationScoped;
4+
5+
@ApplicationScoped
6+
public class UnusedBean {
7+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.quarkus.example.test;
2+
3+
import static org.junit.jupiter.api.Assertions.assertNotNull;
4+
5+
import javax.inject.Inject;
6+
7+
import org.junit.jupiter.api.Test;
8+
9+
import io.quarkus.example.arc.UnusedBean;
10+
import io.quarkus.test.junit.QuarkusTest;
11+
12+
@QuarkusTest
13+
class BeanOnlyInTestCase {
14+
15+
@Inject
16+
UnusedBean unusedBean;
17+
18+
@Test
19+
void assertBeanIsInjected() {
20+
assertNotNull(unusedBean);
21+
}
22+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.quarkus.test.common;
2+
3+
import java.util.ServiceLoader;
4+
import java.util.function.Consumer;
5+
6+
import org.jboss.builder.BuildChainBuilder;
7+
import org.jboss.jandex.DotName;
8+
9+
import io.quarkus.deployment.test.TestDefiningAnnotationBuildItemProvider;
10+
import io.quarkus.runner.RuntimeRunner;
11+
12+
public final class TestAnnotationAsBeanDefiningAnnotationUtil {
13+
14+
private TestAnnotationAsBeanDefiningAnnotationUtil() {
15+
}
16+
17+
public static void makeTestsBeanDefiningAnnotations(RuntimeRunner.Builder builder, Class testClass) {
18+
// this elaborate construct is needed to make sure that if Arc is being used (even though the test module)
19+
// does not depend on it, that QuarkusTest classes will be treaded as "beans", and therefore injection
20+
// of beans into them is possible even those beans are not injected anywhere else
21+
ServiceLoader<TestDefiningAnnotationBuildItemProvider> loader = ServiceLoader
22+
.load(TestDefiningAnnotationBuildItemProvider.class);
23+
for (TestDefiningAnnotationBuildItemProvider provider : loader) {
24+
builder.addChainCustomizer(new Consumer<BuildChainBuilder>() {
25+
@Override
26+
public void accept(BuildChainBuilder buildChainBuilder) {
27+
final TestDefiningAnnotationBuildItemProvider.Output output = provider
28+
.customize(DotName.createSimple(testClass.getName()));
29+
buildChainBuilder.addBuildStep(output.getBuildStep()).produces(output.getProduces()).build();
30+
}
31+
});
32+
}
33+
}
34+
}

test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static io.quarkus.test.common.PathTestHelper.getAppClassLocation;
2020
import static io.quarkus.test.common.PathTestHelper.getTestClassesLocation;
21+
import static io.quarkus.test.common.TestAnnotationAsBeanDefiningAnnotationUtil.makeTestsBeanDefiningAnnotations;
2122

2223
import java.io.Closeable;
2324
import java.io.FileOutputStream;
@@ -126,7 +127,7 @@ private ExtensionState doJavaStart(ExtensionContext context, TestResourceManager
126127
}
127128
originalCl = setCCL(appCl);
128129

129-
RuntimeRunner runtimeRunner = RuntimeRunner.builder()
130+
final RuntimeRunner.Builder builder = RuntimeRunner.builder()
130131
.setLaunchMode(LaunchMode.TEST)
131132
.setClassLoader(appCl)
132133
.setTarget(appClassLocation)
@@ -242,8 +243,11 @@ public boolean test(String className) {
242243
}).produces(TestClassPredicateBuildItem.class)
243244
.build();
244245
}
245-
})
246-
.build();
246+
});
247+
248+
makeTestsBeanDefiningAnnotations(builder, QuarkusTest.class);
249+
250+
RuntimeRunner runtimeRunner = builder.build();
247251
runtimeRunner.run();
248252

249253
Closeable shutdownTask = new Closeable() {

0 commit comments

Comments
 (0)