код модульного тестирования, который использует JPA & JTA - PullRequest
2 голосов
/ 17 октября 2010

Я использую 2 отдельные базы данных, поэтому мне приходится использовать JTA для обработки распределенных транзакций. Так что либо либо БД, либо коммит, либо оба отката.Я использую открытые JPA и JTA. Теперь для модульного тестирования кода с использованием junit?Я получаю следующую ошибку, когда пытаюсь запустить свой код, который обрабатывает распределенные транскрипции. Я разместил похожий вопрос на этом сайте, и кто-то попросил меня сослаться на http://knol.google.com/k/how-to-unit-test-enterprise-java-beans-ejb# Но я не понимаю, что там происходит.1004 *

Ответы [ 3 ]

2 голосов
/ 17 октября 2010

Я использую 2 отдельные базы данных, поэтому мне приходится использовать JTA для обработки распределенных транзакций.Так что либо либо оба БД должны принять, либо оба отката.Я использую открытые JPA и JTA. Теперь для модульного тестирования кода с использованием junit?

Если вы хотите запускать интеграционные тесты вне контейнера и использовать JTA, вам придется

  1. установка автономного менеджера транзакций JTA, например Atomikos , Bitronix и т. Д. (Я выбрал бы Atomikos для его документации)
  2. настройка JTA-совместимых источников данных
  3. оберните все это вместе.

Я настоятельно рекомендую использовать Spring и посмотреть Spring, JPA и JTA с Hibernate и JOTM (но адаптируйте его для использования Atomikos, Bitronix).

Ресурсы

Схожие вопросы

0 голосов
/ 01 декабря 2010

У меня есть приложение Wicket с EJB 3. Производственные работы над Glassfish 2 (Toplink - JPA 1). Модульные тесты работают на OpenEJB 3. Мне нужно было OpenEJB в модульных тестах, чтобы использовать потрясающие интеграционные тесты Wicket.

Я полагаю, у вас есть проект Maven. Если нет, захватите зависимости вручную.

pom.xml:

<dependency>
    <!-- It's provided by Glassfish but while testing OpenEJB needs it explicitly -->
    <groupId>toplink.essentials</groupId>
    <artifactId>toplink-essentials</artifactId>
    <version>2.0-58g</version>
</dependency>

<dependency>
    <!-- not sure about this one but probably it's needed -->
    <groupId>org.glassfish</groupId>
    <artifactId>javax.servlet</artifactId>
    <version>3.0</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.apache.openejb</groupId>
    <artifactId>openejb-core</artifactId>
    <version>3.0.2</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.13</version>
    <scope>test</scope>
</dependency>

Убедитесь, что вы поставили его сразу после <dependencies>.

Класс AbstactOpenEjbTest:

public abstract class AbstractOpenEjbTest {

    private static final String JTA_DATA_SOURCE = "jdbc/SeobserwatorDS";

    protected static InitialContext context;

    @BeforeClass
    public static void createInitialContext() throws Exception {
        setSystemProperties();

        final Properties properties = new Properties();

        properties.setProperty(JTA_DATA_SOURCE, "new://Resource?type=DataSource");
        properties.setProperty(JTA_DATA_SOURCE + ".JdbcDriver", "com.mysql.jdbc.Driver");
        properties.setProperty(JTA_DATA_SOURCE + ".JdbcUrl", "jdbc:mysql://localhost:3306/inne_test");
        properties.setProperty(JTA_DATA_SOURCE + ".UserName", "xxx");
        properties.setProperty(JTA_DATA_SOURCE + ".Password", "yyy");

        context = new InitialContext(properties);
    }

    @BeforeClass
    public static void setSystemProperties() {
        System.setProperty("java.naming.factory.initial", "org.apache.openejb.client.LocalInitialContextFactory");
        System.setProperty("toplink.target-server", "net.nowaker.nhr.seobserwator.web.OpenEjbTransactionController");
        System.setProperty("toplink.ddl-generation", "drop-and-create-tables");
        System.setProperty("toplink.logging.level", "WARNING");
        System.setProperty("toplink.ddl-generation.output-mode", "both");
    }

    @SuppressWarnings("unchecked")
    public AbstractOpenEjbTest() {
        // Execute manually all ServletContextListeners as we are outside the container
    }

    @AfterClass
    public static void removeTables() throws Exception {
        // some clean-up, e.g. delete all data
    }
}

Какой-то странный класс, я не могу вспомнить, для чего он нужен, но нужен:

import javax.transaction.TransactionManager;
import oracle.toplink.essentials.transaction.JTATransactionController;

/**
 * Transaction controller for OpenEJB standalone/embedded and Toplink
 *
 * @see http://qbeukes.blogspot.com/2008/08/toplink-as-your-openejb-persistence.html
 */
public class OpenEjbTransactionController extends JTATransactionController {

    public static final String JNDI_TRANSACTION_MANAGER_NAME = "java:comp/TransactionManager";

    public OpenEjbTransactionController() {
        super();
    }

    @Override
    protected TransactionManager acquireTransactionManager() throws Exception {
        return (TransactionManager) jndiLookup(JNDI_TRANSACTION_MANAGER_NAME);
    }
}

Пример теста:

public class OpenEjbTest extends AbstractOpenEjbTest {

    @Test
    public void shouldAddUserWithStatelessBean() throws Exception {
        // when
        final AuthServiceLocal authService = EjbUtils.lookupBean(AuthServiceLocal.class);
        final CrudServiceLocal crudService = EjbUtils.lookupBean(CrudServiceLocal.class);

        // then
        assertFalse(authService.userExists("nonExistent"));
        final User unmanagedUser = new User(null, "a", "b", "c", "d", 12345678, new Date());
        final User managedUser = crudService.update(unmanagedUser);
        assertNotNull(managedUser.getId());
        assertNotNull(crudService.find(User.class, managedUser.getId()));
    }
}

Дайте мне знать, если это работает для вас.

0 голосов
/ 01 декабря 2010

Другой вариант - использовать OpenEjb для модульного тестирования.

...