注入在 Arquillian 测试中不起作用
Injection doesn't work in Arquillian test
我正在尝试使用 JavaEE 开发简单的应用程序,但目前我被困在 arquillian 测试中。我有一个像这样的 BookRepository class:
package com.pluralsight.bookstore.repository;
import javax.transaction.Transactional;
import static javax.transaction.Transactional.TxType.SUPPORTS;
@Transactional(SUPPORTS)
public class BookRepository {
}
并测试 class BookRepositoryTest :
package com.pluralsight.bookstore.repository;
@RunWith(Arquillian.class)
public class BookRepositoryTest {
@Inject
private BookRepository bookRepository;
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClass(BookRepository.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsManifestResource("META-INF/test-persistence.xml", "persistence.xml");
}
@Test
public void create() {
assertNotNull(bookRepository);
}
}
运行 测试结果:
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 9.864 sec <<< FAILURE!
create(com.pluralsight.bookstore.repository.BookRepositoryTest) Time elapsed: 0.287 sec <<< ERROR!
java.lang.NullPointerException
at com.pluralsight.bookstore.repository.BookRepositoryTest.create(BookRepositoryTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
...
没有任何解释。当我使用 assertNotNull 检查时,bookRepository 始终为 null,因此我猜注入在这里不起作用。项目结构如下所示:
我尝试寻找答案已经有一段时间了,但我仍然在同一个地方。对于容器,我 运行 使用 wildfly 遥控器进行测试,并在后台使用 WildFly 运行ning。
在此先感谢您的帮助!
Wildfly 是一个 Java EE 7 兼容的 AS,在 JavaEE 7 CDI beans 中,如果有注释,默认情况下会被发现,请查看 Default CDI Enablement in Java EE 7,这可能是你的情况一个空 beans.xml。
因此,要注入 BookRepository
,您必须添加范围注释(参见 CDI scopes),例如 @ApplicationScoped
:
@ApplicationScoped
@Transactional(SUPPORTS)
public class BookRepository {
}
或者您必须包含一个 beans.xml,具有发现模式 all
,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<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"
bean-discovery-mode="all">
</beans>
将它放在 src/test/resources 下以将其包含在您的测试中修改如下:
package com.pluralsight.bookstore.repository;
@RunWith(Arquillian.class)
public class BookRepositoryTest {
@Inject
private BookRepository bookRepository;
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClass(BookRepository.class)
.addAsManifestResource("META-INF/beans.xml", "beans.xml")
.addAsManifestResource("META-INF/test-persistence.xml", "persistence.xml");
}
//...
}
好的,我终于成功了。显然我使用了错误的“@Inject”注解。我使用的是 arquillian,而不是 javax。我改变了
import org.jboss.arquillian.core.api.annotation.Inject;
在我的测试用例中 class 到
import javax.inject.Inject;
而且效果非常好。追踪起来真的很烦人,实际上我是靠运气找到它的,所以我希望这对以后的人有所帮助。
我正在尝试使用 JavaEE 开发简单的应用程序,但目前我被困在 arquillian 测试中。我有一个像这样的 BookRepository class:
package com.pluralsight.bookstore.repository;
import javax.transaction.Transactional;
import static javax.transaction.Transactional.TxType.SUPPORTS;
@Transactional(SUPPORTS)
public class BookRepository {
}
并测试 class BookRepositoryTest :
package com.pluralsight.bookstore.repository;
@RunWith(Arquillian.class)
public class BookRepositoryTest {
@Inject
private BookRepository bookRepository;
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClass(BookRepository.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsManifestResource("META-INF/test-persistence.xml", "persistence.xml");
}
@Test
public void create() {
assertNotNull(bookRepository);
}
}
运行 测试结果:
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 9.864 sec <<< FAILURE!
create(com.pluralsight.bookstore.repository.BookRepositoryTest) Time elapsed: 0.287 sec <<< ERROR!
java.lang.NullPointerException
at com.pluralsight.bookstore.repository.BookRepositoryTest.create(BookRepositoryTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
...
没有任何解释。当我使用 assertNotNull 检查时,bookRepository 始终为 null,因此我猜注入在这里不起作用。项目结构如下所示:
我尝试寻找答案已经有一段时间了,但我仍然在同一个地方。对于容器,我 运行 使用 wildfly 遥控器进行测试,并在后台使用 WildFly 运行ning。 在此先感谢您的帮助!
Wildfly 是一个 Java EE 7 兼容的 AS,在 JavaEE 7 CDI beans 中,如果有注释,默认情况下会被发现,请查看 Default CDI Enablement in Java EE 7,这可能是你的情况一个空 beans.xml。
因此,要注入 BookRepository
,您必须添加范围注释(参见 CDI scopes),例如 @ApplicationScoped
:
@ApplicationScoped
@Transactional(SUPPORTS)
public class BookRepository {
}
或者您必须包含一个 beans.xml,具有发现模式 all
,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<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"
bean-discovery-mode="all">
</beans>
将它放在 src/test/resources 下以将其包含在您的测试中修改如下:
package com.pluralsight.bookstore.repository;
@RunWith(Arquillian.class)
public class BookRepositoryTest {
@Inject
private BookRepository bookRepository;
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClass(BookRepository.class)
.addAsManifestResource("META-INF/beans.xml", "beans.xml")
.addAsManifestResource("META-INF/test-persistence.xml", "persistence.xml");
}
//...
}
好的,我终于成功了。显然我使用了错误的“@Inject”注解。我使用的是 arquillian,而不是 javax。我改变了
import org.jboss.arquillian.core.api.annotation.Inject;
在我的测试用例中 class 到
import javax.inject.Inject;
而且效果非常好。追踪起来真的很烦人,实际上我是靠运气找到它的,所以我希望这对以后的人有所帮助。