问题是 Wildfly 中根本没有 EJBContainer。我不确定这是怎么可能的,因为根据平台规范 EJBContainer 应该在那里。然而,我们需要使用不同的东西,它是 Arquillian。这篇文章的灵感来自许多其他文章,比如这篇文章,但是这里建议的解决方案是使用与常规部署相同的 Wildfly 安装进行测试,这对我来说似乎更好。
有必要仔细遵循以下提示。然后它将起作用。
步骤零 - 准备:让我们准备一些可以用于测试的东西。
让我们有一个常规的 Maven JavaEE 项目,即:
demoproj
demoproj-ear
demoproj-ejb
demoproj-war
我正在使用 NetBeans,但是即使对于其他 IDE,以下步骤也不应该有很大不同。让我们创建一些东西,比如实体 bean、持久性单元和会话 bean,当然是为了测试一些东西。我创建了一个使用 NetBeans 的演示持久性单元、一个使用数据库的实体和一个来自该实体的会话 bean。
第一步:我们在 pom.xml od demoproj(即主项目)中添加如下代码:
<properties>
<junit-version>4.11</junit-version>
<arquillian-version>1.1.4.Final</arquillian-version>
<arquillian-wildfly-version>8.1.0.Final</arquillian-wildfly-version>
<arquillian-transaction-version>1.0.1.Final</arquillian-transaction-version>
<javaee-server-home>/Java/wildfly-8.1.0.Final</javaee-server-home>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee-api-version}</version>
</dependency>
<!-- -JUNIT-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
</dependency>
<!-- rquillian itself-->
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>${arquillian-version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<!-- this is in an extention to arquillian it is optional-->
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-transaction-bom</artifactId>
<version>${arquillian-transaction-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- this is container adapter for wildfly-->
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-arquillian-container-embedded</artifactId>
<version>${arquillian-wildfly-version}</version>
</dependency>
<!-- this is the wildfly emb.container - BUT eventually it is not a fully blown emb.container-->
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-embedded</artifactId>
<version>${arquillian-wildfly-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<!-- compiler plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin-version}</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<!-- maven ear plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>${ear-plugin-version}</version>
<configuration>
<generateModuleId>true</generateModuleId>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<!-- ejb plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>${ejb-plugin-version}</version>
<configuration>
<ejbVersion>${ejb-spec-version}</ejbVersion>
</configuration>
</plugin>
<!-- war plugin -skinny wars mode! -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${war-plugin-version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
<webResources>
<resource>
<filtering>true</filtering>
<directory>src/main/webapp</directory>
<includes>
<include>**/web.xml</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
</plugin>
</plugins>
</pluginManagement>
</build>
第二步:我们将以下内容添加到 demoproj-ejb 的 pom.xml 的依赖项部分:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-arquillian-container-embedded</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-embedded</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-transaction-jta</artifactId>
<scope>test</scope>
</dependency>
将此添加到 demoproj-ejb 的插件部分:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Dfile.encoding=UTF-8</argLine>
<forkCount>1C</forkCount>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<jboss.home>${javaee-server-home}</jboss.home>
</systemPropertyVariables>
<redirectTestOutputToFile>false</redirectTestOutputToFile>
</configuration>
</plugin>
第三步:让我们创建测试单元。如果我们使用普通的 IDE 函数,我们会得到如下内容:
package com.demopack.demoproj;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class DemoBeanLocalTest {
public DemoBeanLocalTest() {
}
@Before
public void setUp() {
}
@Test
public void testBusinessMethod() {
}
}
现在我们需要@RunWith(Arquillian.class)
在类头之前添加,你应该删除默认构造函数并在测试类中添加以下代码:
@EJB
DemoBeanLocal demoBean;
@Deployment
public static JavaArchive createDeployment() {
JavaArchive jar = ShrinkWrap.create(JavaArchive.class);
jar.addAsResource("test-persistence.xml", "META-INF/persistence.xml");
jar.addPackage("com.demopack.demoproj");
jar.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
return jar;
}
然后你可以像往常一样添加一些测试方法。整个测试类可能如下所示:
package com.demopack.demoproj;
import javax.ejb.EJB;
import junit.framework.Assert;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(Arquillian.class)
public class DemoBeanLocalTest {
@EJB
DemoBeanLocal demoBean;
@Deployment
public static JavaArchive createDeployment() {
JavaArchive jar = ShrinkWrap.create(JavaArchive.class);
jar.addAsResource("test-persistence.xml", "META-INF/persistence.xml");
jar.addPackage("com.demopack.demoproj");
jar.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
return jar;
}
@Before
public void setUp() {
}
@Test
public void testBusinessMethod() {
Assert.assertEquals("test test", demoBean.businessMethod("test"));
}
}
第四步:快完成了,但还剩下一件非常重要的事情:在 demoproj-ejb 下创建文件夹并从src/test/resources
那里复制并重命名为.persistence.xml
src/main/resources/META-INF
test-persistence.xml
确保数据库正在运行,安装了有效的驱动程序,使用了正确的数据源等。在我的情况下,大多数问题都是由此类问题引起的。
而已!现在您应该清理并构建demoproj
,如果一切正常,您可以像以前一样使用普通的 NetBeans 测试功能。享受!
更新如果您更喜欢使用远程实例(在远程服务器上或在同一台机器上运行的实例),我建议由于某些性能提升,您应该更改代码的以下部分:
在主项目的 pom.xml 中:
交换:
`<artifactId>wildfly-arquillian-container-embedded</artifactId>` for
`<artifactId>wildfly-arquillian-container-remote</artifactId>`.
消除:
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-embedded</artifactId>
<version>${arquillian-wildfly-version}</version>
</dependency>
然后在 demoproj-ejb 的 pom.xml 中做同样的事情。