2015-06-17 1 views
4

Я пытаюсь сделать тестирование интеграции с следующим стеком:Невозможно Вводят EntityManager в интеграции тестировании JPA С Arquillian и WildFly

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) и I 'm может вводить зависимости, но инъекция EntityManager оказывается проблемой. Выделение поля управления сущностью всегда приводит к NullPointerException.

Я видел много статей (включая this и this), но я все еще не могу получить эту, казалось бы, простую вещь для работы.

Пожалуйста, смотрите ниже моей 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.

Пожалуйста, что я делаю неправильно?

+0

Я не осведомлен с Arquillian, но управляемый контейнером entitymagner доступен только на сервере. Я считаю, что вам придется использовать управляемый приложениями entitymanager. –

+0

Есть две проблемы с этим. 1. Это не сработает. Если вы не можете ввести EM, вы не сможете вводить EMF (любезно поправьте меня, если я ошибаюсь). 2. Даже если это действительно сработало, это делает мой «интеграционный тест» намного менее прочным, так как архитектура уже не такая же, как у производственной среды (устойчивость к транзакциям с контейнером против бина) Arquillian - это интеграционное тестирование окружающей среды и, как ожидается, будет создавать поддерживающие серверные компоненты. Это не то же самое, что работать только в JUnit/TestNG, который будет SE-подобным приложением. –

ответ

0

Использовать управляемый объект entitymanager.

@PersistenceUnit 
EntityManagerFactory emf; 

и создать EntityManager с помощью

EntityManager em = emf.createEntityManager(); 

контейнер удалось EntityManager создается и вводится самим контейнером. Если вы не находитесь в серверной среде, вам необходимо использовать application managed persistence context.

+0

Привет, спасибо, что нашли время, чтобы попытаться помочь мне. Я просто попробовал этот подход (просто чтобы быть уверенным) и неудивительно, что это не сработало. Есть две проблемы с этим. 1. Это не сработает. Если вы не можете ввести EM, вы не сможете вводить EMF (любезно поправьте меня, если я ошибаюсь). 2. Даже если это действительно сработало, это делает мой «интеграционный тест» намного менее прочным, так как архитектура больше не такая же, как у производственной среды (устойчивость к транзакциям с контейнером против бина) Arquillian - это интеграционное тестирование окружающей среды и, как ожидается, будет создавать поддерживающие серверные компоненты. –

0

Я предполагаю, что в вашем файле контекста отсутствует менеджер транзакций + фабрика заметок сущностей. Настройте оба параметра в test-persistence.xml, затем создайте фабрику-менеджер объектов в качестве свойства диспетчера транзакций.

+0

Привет, Маркус, спасибо, что нашли время из вашего расписания, чтобы помочь мне с ответом. Не могли бы вы предоставить примеры фрагментов для реализации вашего решения? Заранее спасибо. –

1

просто не используйте сварные швы, источники данных грехов не могут быть покрыты CI и DI. вероятно, вы можете издеваться над его Mokito и остаться с легкой Weld,

<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 DataSource) или управляемый 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

1

Как заявил @ Соловьев Дмитрий, вы используете контейнер CDI для вашего теста интеграции, который позволяет использовать только CDI.

Есть два варианта, которые я вижу:

Сначала один является использование wildfly встраиваемого контейнера, выполненным в вашем Maven проекте, поэтому во время Maven фазы запуска интеграционных-тестов, wildfly будет загружен и ваш тест пакет будет развернут к нему. Таким образом, с ExampleDS он будет работать нормально, поскольку он поставляется с Wildfly из коробки.

См this post подробности

Второй один будет состоять в использовании не Arquillian для тестирования интеграции. Поэтому, если ваш интеграционный тест охватывает только управляемые компоненты (не сеансовые компоненты, специфические ресурсы Wildfly, ...), вы можете просто создать экземпляр контейнера CDI перед выполнением теста (в @Before или @BeforeClass аннотированный метод с использованием, например, Junit) а затем создайте экземпляр EntityManager с помощью класса EntityManagerFactory, ссылаясь на ваш блок персистентности, используемый для этого теста интеграции. С помощью этого метода вы также можете создать производителей CDI для внедрения других ресурсов для вашего теста интеграции, издевательства, в зависимости от объема вашего теста.

Maven зависимость

<dependency> 
    <groupId>org.jboss.weld.se</groupId> 
    <artifactId>weld-se</artifactId> 
    <version>2.1.2.Final</version> 
    <scope>test</scope> 
</dependency> 

Тест класса

import org.jboss.weld.environment.se.Weld; 
import org.jboss.weld.environment.se.WeldContainer; 
import org.junit.*; 

public class ExampleIT { 

    private EntityManager em; 

    protected static Weld weld; 
    protected static WeldContainer container; 

    @BeforeClass 
    public static void init() { 
     weld = new Weld(); 
     container = weld.initialize(); 
    } 

    @AfterClass 
    public static void close() { 
     weld.shutdown(); 
    } 

    @Before 
    private void before(){ 
    em = Persistence.createEntityManagerFactory("MyPersistenceUnit").createEntityManager(); 
    } 

    @Test 
    public void testToto(){ 
     // Do something with entity manager ... 
    } 

} 

Я обычно выбирают второе решение для интеграции тестов, потому что это проще в установке, чем Arquillian тестов, и быстрее выполнять.