我们从Enterprise JavaBeans开发人员那里听到的最常见的请求之一就是需要改进的单元/集成测试支持。
EJB 3.1 Specification引入了EJB 3.1 Embeddable API,用于在Java SE环境中执行EJB组件。
与传统的基于Java EE服务器的执行不同,可嵌入式用法允许客户端代码及其相应的企业bean在同一JVM和类加载器中运行。 这为测试,脱机处理(例如批处理)以及在桌面应用程序中使用EJB编程模型提供了更好的支持。
[…]可嵌入的EJB容器为托管环境提供了对Java EE运行时中存在的相同基本服务的支持:注入,对组件环境的访问,容器管理的事务等。通常,企业bean组件不了解他们在其中运行的一种托管环境。 这使得企业组件在各种测试和部署方案中都具有最大的可重用性,而无需进行大量的返工。
让我们看一个例子。
首先创建一个Maven项目,然后添加可嵌入的GlassFish依赖项。
我选择使用TestNG测试框架,但JUnit应该也能正常工作。
<dependencies>
<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.4</version>
<scope>test</scope>
</dependency>
<!--
The javaee-api is stripped of any code and is just used to
compile your application. The scope provided in Maven means
that it is used for compiling, but is also available when
testing. For this reason, the javaee-api needs to be below
the embedded Glassfish dependency. The javaee-api can actually
be omitted when the embedded Glassfish dependency is included,
but to keep your project Java-EE 6 rather than GlassFish,
specification is important.
-->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
这是一个简单的Stateless
会话Bean:
@Stateless
public class HelloWorld {
public String hello(String message) {
return "Hello " + message;
}
}
它通过无接口视图公开业务方法。
它没有可用于嵌入执行的特殊API。
以下是一些测试代码,用于在可嵌入容器中执行Bean:
public class HelloWorldTest {
private static EJBContainer ejbContainer;
private static Context ctx;
@BeforeClass
public static void setUpClass() throws Exception {
// Instantiate an embeddable EJB and search the
// JVM class path for eligible EJB modules or directories
ejbContainer = EJBContainer.createEJBContainer();
// Get a naming context for session bean lookups
ctx = ejbContainer.getContext();
}
@AfterClass
public static void tearDownClass() throws Exception {
// Shutdown the embeddable
ejbContainer.close();
}
@Test
public void hello() throws NamingException {
// Retrieve a reference to the session bean using a portable
// global JNDI name
HelloWorld helloWorld = (HelloWorld)
ctx.lookup("java:global/classes/HelloWorld");
// Do your tests
assertNotNull(helloWorld);
String expected = "World";
String hello = helloWorld.hello(expected);
assertNotNull(hello);
assertTrue(hello.endsWith(expected));
}
}
源代码在GitHub上的ejb31-embeddable
文件夹下可用。
有关JPA示例的分步教程,请阅读使用嵌入式EJB容器从NetBeans文档测试企业应用程序 。
尽管此新API向前迈了一大步,但我仍然对这种方法有疑问:您正在将容器进行测试。 这需要一个与您的生产环境不同的专用容器。
在Java EE 6测试第二部分中 ,我将介绍Arquillian和ShrinkWrap 。
Arquillian是一个功能强大的面向容器的测试框架,位于TestNG和JUnit之上,使您能够在您选择的容器上创建生产环境,并仅在该环境中执行测试(使用数据源,JMS目标以及许多其他工具)。您希望在生产环境中看到的其他配置)。 Arquillian并没有将您的运行时带到测试中,而是将您的测试带到了运行时中。