У меня есть приложение 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()));
}
}
Дайте мне знать, если это работает для вас.