Как провести модульное тестирование CDI с приваркой?
Я хочу использовать сварки для модульного тестирования CDI. Тем не менее, я застрял с этой проблемой, что Weld не может разрешить бины. Я создал мини-проект, чтобы продемонстрировать проблему с gradle для строительства.
У меня есть следующие файлы в <project-root>
папка:
./build.gradle
./src/main/java/cdi/Book.java
./src/main/resources/META-INF/beans.xml
./src/test/java/cdi/BookTest.java
./src/test/resources/META-INF/beans.xml
Содержание каждого файла указано ниже.
build.gradle
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile 'org.jboss.weld.se:weld-se:2.0.4.Final'
testCompile 'junit:junit:4.11'
}
Book.java
package cdi;
public class Book {
private String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
BookTest.java
package cdi;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class BookTest {
private static Weld weld;
private static WeldContainer weldContainer;
@BeforeClass
public static void setupClass() {
weld = new Weld();
weldContainer = weld.initialize();
}
@AfterClass
public static void teardownClass() {
weld.shutdown();
}
@Test
public void dummyTest() {
Book book = weldContainer.instance().select(Book.class).get();
book.setTitle( "foobar");
assertEquals("foobar", book.getTitle());
}
}
beans.xml(два beans.xml
под основной / и тестовой / идентичны.)
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
Когда я строю проект с gradle clean build
Я получаю сообщение об ошибке, которое указано ниже. Я гуглил вокруг, но не мог заставить это работать.
Большое спасибо за Вашу помощь.
org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308 Unable to resolve any beans for Types: [class cdi.Book]; Bindings: [QualifierInstance{annotationClass=interface javax.enterprise.inject.Any, values={}, hashCode=868729182}]
at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:824)
at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:78)
at cdi.BookTest.dummyTest(BookTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:80)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:47)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:103)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
3 ответа
Вы должны попробовать "иглу": http://needle.spree.de/overview.
Он позаботится о простых задачах макетирования /DI и не требует контейнера с полным стеком. В вашем случае вы могли бы просто использовать
@Rule
public final NeedleRule needle = new NeedleRule();
@Inject
private Book book;
...
У меня была точно такая же проблема, и она вызвана тем, что Gradle поместил файл META-INF/beans.xml в build/resources/ вместо build/classes.
Насколько я понимаю, Weld не будет сканировать классы без файла beans.xml.
Ужасное исправление - изменить файл build.gradle для копирования файлов перед запуском теста. Это работает для меня, и я не знаю ни о каких нежелательных побочных эффектах в настоящее время.
Изменения в файле Gradle.
test.doFirst {
copy {
from 'build/resources/main/META-INF/beans.xml'
into 'build/classes/main/META-INF/'
}
copy {
from 'build/resources/test/META-INF/beans.xml'
into 'build/classes/test/META-INF/'
}
}
Также я создал CDI-Unit http://jglue.org/cdi-unit/
В дереве исходных текстов есть пример проекта gradle: https://github.com/BrynCooke/cdi-unit/tree/master/cdi-unit-tests-gradle