Testes com Wildfly 8 e NetBeans
Pergunta
Eu tenho problemas para fazer Wildfly testes em NetBeans e Maven.Eu sou capaz de lançar o aplicativo do IDE, eu posso até depurá-lo com o Netbeans depurador, no entanto assim que eu começar a testes de unidade, recebo o seguinte erro:
No EJBContainer provider available: no provider names had been found.
javax.ejb.EJBException
at javax.ejb.embeddable.EJBContainer.reportError(EJBContainer.java:216)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:146)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:102)
at cz.interactsys.ejb.StatefulSessionBeanTest.setUp(StatefulSessionBeanTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
O código padrão é semelhante ao seguinte:
int numberA = 1;
int numberB = 2;
EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer();
MyBean instance = (MyBean) container.getContext().lookup("java:global/classes/MyBean");
int expResult = 3;
int result = instance.plusOne(1);
assertEquals(expResult, result);
container.close();
Obrigado antecipadamente.
Solução
O problema é que não há EJBContainer em Wildfly em tudo.Eu não sou certo como isto é possível dado que EJBContainer devem ser de acordo com as especificações da plataforma.no entanto precisamos usar algo diferente, e é o Arquillian.Este texto foi inspirado por inúmeros outros artigos, principalmente este, no entanto , a solução sugerida aqui é usar o mesmo Wildfly de instalação para testes para a implantação regular, o que parece melhor para mim.
É necessário seguir as dicas a seguir com atenção.Em seguida, ele irá trabalhar.
A etapa zero - preparação: Vamos preparar algo que pode utilizar para testar.
Vamos ter um regular Maven JavaEE projeto, por exemplo:
demoproj
demoproj-ear
demoproj-ejb
demoproj-war
Eu estou usando o NetBeans, no entanto, as etapas a seguir não deve ser muito diferente até mesmo para outros IDEs.Vamos criar algumas coisas como entidade feijão, persistência unidade, e beans de sessão do curso, a fim de ter algo para teste.Eu criei uma demonstração de persistência unidade usando o NetBeans, uma entidade usando o banco de dados, e um bean de sessão da entidade.
Passo um: Adicionamos o seguinte código no pom.xml od demoproj (i.e.o projeto mestre):
<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>
Passo dois: Vamos adicionar o seguinte em dependências da seção de pom.xml de demoproj-ejb:
<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>
Adicionar este na seção de plugins do 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>
Passo três: Vamos criar a unidade de teste.Se usar um normal IDE função, temos algo como o seguinte:
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() {
}
}
Agora precisamos adicionar @RunWith(Arquillian.class)
pouco antes do cabeçalho da classe, você deve remover o construtor padrão e adicione o seguinte código no interior do teste de classe:
@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;
}
Em seguida, você pode adicionar alguns métodos de teste, como de costume.Toda a classe de teste pode ter a seguinte aparência:
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"));
}
}
Passo quatro: Quase feito, mas uma coisa mais importante é a esquerda:em demoproj-criar ejb src/test/resources
pasta e copie lá persistence.xml
a partir de src/main/resources/META-INF
e mude o nome para test-persistence.xml
.
Certifique-se de que o banco de dados está em execução, um válido driver é instalado, corrigir fonte de dados utilizada, etc.No meu caso, a maioria dos problemas foi causada por problemas deste tipo.
Que é isso! Agora, você deve limpar e construir demoproj
e se tudo vai estar OK, você pode usar normal NetBeans função de teste como você está acostumado.Divirta-se!
ATUALIZAÇÃO Se você prefere usar uma instância remota (ou em um servidor remoto ou de uma instância em execução na mesma máquina), o que eu recomendo, devido a certas ganho de desempenho, você deve alterar as seguintes partes do código:
No pom.xml no projeto mestre:
Exchange:
`<artifactId>wildfly-arquillian-container-embedded</artifactId>` for
`<artifactId>wildfly-arquillian-container-remote</artifactId>`.
Remover:
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-embedded</artifactId>
<version>${arquillian-wildfly-version}</version>
</dependency>
Em seguida, fazer o mesmo em pom.xml de demoproj-ejb.