maven – 无法使用Arquillian和WildFly在JPA集成测试中注入EntityManager

我正在尝试使用以下堆栈进行集成测试:

App server: Embedded WildFly
CDI container: Weld
Database: In-memory H2
ORM: Hibernate/JPA
Platform: Java 8
OS: Mac OS X 10.10

我已经使用Arquillian设置了基本的集成测试(如here所做),我能够注入依赖项,但注入EntityManager证明是一个挑战.取消引用实体管理器字段总是会导致NullPointerException.

我见过很多文章(包括thisthis),但我仍然无法让这个看起来很简单的事情发挥作用.

请参阅下面的pom.xml

  <dependencies>
    <dependency>
      <groupId>org.jboss.spec</groupId>
      <artifactId>jboss-javaee-7.0</artifactId>
      <version>1.0.0.Final</version>
      <type>pom</type>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.1</version>
      <scope>test</scope>
    </dependency>

    <!-- JUnit Container Implementation for the Arquillian Project -->
    <dependency>
      <groupId>org.jboss.arquillian.junit</groupId>
      <artifactId>arquillian-junit-container</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.jboss.arquillian.protocol</groupId>
      <artifactId>arquillian-protocol-servlet</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.jboss.arquillian.container</groupId>
      <artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
      <version>1.0.0.CR3</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.jboss.arquillian.extension</groupId>
      <artifactId>arquillian-persistence-dbunit</artifactId>
      <version>1.0.0.Alpha7</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.jboss.weld</groupId>
      <artifactId>weld-core</artifactId>
      <version>1.1.5.Final</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.6.4</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.jboss.arquillian</groupId>
        <artifactId>arquillian-bom</artifactId>
        <version>1.1.8.Final</version>
        <scope>import</scope>
        <type>pom</type>
      </dependency>
    </dependencies>
  </dependencyManagement>

测试的persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="
        http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="test" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>com.xyz.hellomaven.DummyEntity</class>

    <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
    <!--<jta-data-source>java:/DefaultDS</jta-data-source>-->
    <!--<jta-data-source>jdbc/arquillian</jta-data-source>-->

    <properties>
      <property name="hibernate.show_sql" value="true" />
      <property name="hibernate.hbm2ddl.auto" value="update"/>
      <!--<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />-->
    </properties>
  </persistence-unit>
</persistence>

测试用例

@RunWith(Arquillian.class)
public class GreeterTest {

  @Inject
  private Greeter instance; // Injection works!

  @PersistenceContext
  private EntityManager em; // Null pointer.

  public GreeterTest() {
  }

  @Deployment
  public static WebArchive createDeployment() {
    return ShrinkWrap.create(WebArchive.class)
        .addClasses(Greeter.class, PhraseBuilder.class, DummyInterceptor.class)
        .addAsResource("logging.properties", "META-INF/logging.properties")
        .addAsResource("test-persistence.xml", "META-INF/persistence.xml")
        .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
  }

  @Test
  public void testCreateGreeting() {
    System.out.println("createGreeting");
    assertEquals("Hello, Steve!", instance.createGreeting("Steve"));
  }

  @Test
  public void testPersistence() {
    DummyEntity de = new DummyEntity();
    de.setId(1l);
    de.setName("Petr Cech");
    de.setAge(10);
    em.persist(de);

    Query q = em.createQuery("SELECT d.age FROM DummyEntity d");
    assertEquals(10, q.getResultList().get(0));
  }
}

完整的Maven项目可用on GitHub.

请问我做错了什么?

最佳答案 只是不使用焊接,罪孽数据源超出CI和DI可能涵盖的范围.也许你可以用Mokito嘲笑它,并保持光焊接,

<dependency>
      <groupId>org.jboss.arquillian.container</groupId>
      <artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
      <version>1.0.0.CR3</version>
      <scope>test</scope>
</dependency>

但是,如果你想处理真正的数据库使用托管jboss(ExampleDS是一个演示jboss h2数据源)或管理glassfish而不是.

        <dependency>
            <groupId>org.jboss.as</groupId>
            <artifactId>jboss-as-arquillian-container-managed</artifactId>
            <version>7.1.1.Final</version>
            <scope>test</scope>
        </dependency>

REF. https://github.com/arquillian/arquillian-examples/blob/master/arquillian-persistence-tutorial/pom.xml

点赞