Каков наилучший способ для unit test компонента EJB3 без необходимости развертывания компонента

Я хотел бы иметь JUnit (или другую) систему, в которой предприятие beans может быть протестировано в макетной среде, чтобы все ресурсы /beans и т.д. были введены локально. Предприятию beans не должно быть этого. Все виды инъекций должны поддерживаться.

  • Я хотел бы иметь плагин maven для этого, чтобы тесты можно запускать из сборки maven.
  • Транзакции не требуются во время модульных тестов, для этого потребуется полная контейнер.

Знаете ли вы о таком плагине maven или тестовой платформе? Опыт с ним?

Ответы

Ответ 1

Не обязательно самый простой способ, но мне удалось получить эту работу с использованием JBoss-встраиваемого контейнера EJB3.0 с большой помощью Java Persistence with Hibernate

Для начала я не знаю о плагинах/зависимостях maven для этого, поэтому мне пришлось локально установить его:

(1) Загрузите jboss-EJB-3.0_Embeddable_ALPHA_9.zip из downloads

(2) Этот zipfile содержит два важных JAR:

  • jboss-ejb3-all.jar
  • thirdparty-all.jar

(3) Установите эти JAR в свой локальный репозиторий (используйте свои собственные инициалы вместо nkl):

mvn install:install-file \
    -Dfile=jboss-ejb3-all.jar \
    -DgroupId=nkl.jboss.embedded \
    -DartifactId=jboss-ejb3-all \
    -Dversion=3.0-alpha-9

mvn install:install-file \
    -Dfile=thirdparty-all.jar \
    -DgroupId=nkl.jboss.embedded \
    -DartifactId=thirdparty-all \
    -Dversion=3.0-alpha-9

(4) Если все прошло хорошо, теперь у вас должно быть два каталога в локальном репозитории.

(5) Теперь добавьте следующие зависимости к вашему pom.xml

    <dependency>
      <groupId>nkl.jboss.embedded</groupId>
      <artifactId>jboss-ejb3-all</artifactId>
      <version>3.0-alpha-9</version>
    </dependency>
    <dependency>
      <groupId>nkl.jboss.embedded</groupId>
      <artifactId>thirdparty-all</artifactId>
      <version>3.0-alpha-9</version>
    </dependency>

(6) Мне также нужно было добавить зависимости для HSQLDB и SLF4J

(7) Вам нужно скопировать некоторые файлы из каталога conf zipfile в каталог src/main/resources вашего проекта:

  • default.persistence.properties
  • ejb3-interceptors-aop.xml
  • embedded-jboss-beans.xml
  • jndi.properties

(8) Я создал свои собственные файлы beans.xml и persistence.xml в src/main/resources/META-INF:

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd" xmlns="urn:jboss:bean-deployer">
  <bean name="messageDSBootstrap" class="org.jboss.resource.adapter.jdbc.local.LocalTxDataSource">
    <property name="jndiName">java:/messageDS</property>
    <property name="driverClass">org.hsqldb.jdbcDriver
    </property>
    <property name="connectionURL">jdbc:hsqldb:test</property>
    <property name="minSize">0</property>
    <property name="maxSize">10</property>
    <property name="blockingTimeout">1000</property>
    <property name="idleTimeout">30000</property>
    <property name="transactionManager">
      <inject bean="TransactionManager" />
    </property>
    <property name="cachedConnectionManager">
      <inject bean="CachedConnectionManager" />
    </property>
    <property name="initialContextProperties">
      <inject bean="InitialContextProperties" />
    </property>
  </bean>
  <bean name="messageDS" class="java.lang.Object">
    <constructor factoryMethod="getDatasource">
      <factory bean="messageDSBootstrap" />
    </constructor>
  </bean>
</deployment>

<persistence 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_1_0.xsd"
  version="1.0">
  <persistence-unit name="jpa">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:/messageDS</jta-data-source>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
      <property name="hibernate.show_sql" value="true" />
      <property name="hibernate.format_sql" value="true" />
      <property name="hibernate.hbm2ddl.auto" value="create" />
    </properties>
  </persistence-unit>
</persistence>

(9) Я создал unit test следующим образом, используя дополнительную информацию из здесь.

package org.nkl;

import java.io.File;

import javax.naming.InitialContext;

import org.jboss.ejb3.embedded.EJB3StandaloneBootstrap;
import org.jboss.ejb3.embedded.EJB3StandaloneDeployer;
import org.junit.Test;
import org.nkl.model.MessageHandler;

public class BasicTest {

    @Test
    public void testEjb() throws Exception {
        EJB3StandaloneBootstrap.boot(null);
        EJB3StandaloneBootstrap.deployXmlResource("META-INF/beans.xml");
        EJB3StandaloneDeployer deployer = EJB3StandaloneBootstrap
                .createDeployer();

        deployer.getArchives().add(new File("target/classes").toURI().toURL());

        deployer.create();
        deployer.start();
        InitialContext context = new InitialContext();
        MessageHandler messageHandler = (MessageHandler) context
                .lookup("MessageHandlerBean/local");
        messageHandler.saveMessages();
        messageHandler.showMessages();
        EJB3StandaloneBootstrap.shutdown();
    }
}

(10) Это использует простой SLSB, например:

package org.nkl.ejb;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.nkl.model.Message;
import org.nkl.model.MessageHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Stateless
public class MessageHandlerBean implements MessageHandler {

    @PersistenceContext
    private EntityManager em;

    Logger logger = LoggerFactory.getLogger(MessageHandlerBean.class);

    public void saveMessages() {
        logger.info("In saveMessages");
        em.persist(new Message("Hello World"));
    }

    @SuppressWarnings("unchecked")
    public void showMessages() {
        logger.info("In showMessages");
        List messages = em.createQuery(
                "select m from Message m order by m.text asc").getResultList();
        for (Object o : messages) {
            logger.info(((Message) o).getText());
        }
    }
}

(11) И класс сущности сообщения, например:

package org.nkl.model;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "MESSAGES")
public class Message {
    @Id
    @GeneratedValue
    @Column(name = "MESSAGE_ID")
    private Long id;
    @Column(name = "MESSAGE_TEXT")
    private String text;
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "NEXT_MESSAGE")
    private Message nextMessage;

    public Message(String text) {
        this.text = text;
    }

    Message() {}

    // setters/getters not shown.

}

Давайте просто скажем, что в этом подходе есть несколько камней преткновения.

Важно делать с порядком зависимостей.

Удачи!

Ответ 2

Я должен предупредить, что встроенный JBoss - беспорядок. Тебе не нужно верить моему слову. Смотрите форумы для себя. Это альфа всеми возможными способами. Теперь все может сработать для вас, но кто знает, какие ошибки все еще ждут там... Предполагая, что ваш проект будет жить долгое время.. что риск.

Вы можете попробовать OpenEJB. Он ограничен в некоторых аспектах (с точки зрения гибкости), но он очень прост в использовании и полностью соответствует спецификации. Есть несколько ссылок, таких как this и this, Скачайте его и попробуйте. Кстати, OpenEJB привлек мое внимание, прочитав сообщения JBoss Embedded Forum... от гневных пользователей, указывающих альтернативы.

Лично я решил создать для своих проектов своего рода макетный контейнер, который позволяет мне проверять почти все, что мне нужно. Для сохранения я использую Hibernate Entity Manager + HSQL. Мне потребовалась неделя, но мои команды (2 пока) очень довольны этим. Я сделаю это с открытым исходным кодом, если это возможно.

Последний вариант ejb3unit.