Estamos pasando de usar TestNG con un JBoss incrustado a usar Arquillian con un servidor remoto.anotaciones @BeforeClass que invocan métodos dos veces cuando se usa Arquillian en el servidor remoto
Estamos ejecutando una prueba simple que tiene un método anotado con @BeforeClass que realiza alguna configuración de prueba. Después de una gran cantidad de búsquedas, parece que el método de configuración se llama dos veces: una vez en la consola donde estamos ejecutando nuestro comando Maven para ejecutar la prueba y otra vez cuando la guerra de prueba se implementa en nuestro servidor remoto y se ejecuta la prueba. Estos son dos JVMS separados: uno que se ejecuta fuera del contenedor y otro que se ejecuta dentro del contenedor. Mi preferencia es simplemente ejecutar la última.
¿Es este el comportamiento que debería esperar o hay algo que me puede estar perdiendo?
Por ahora, en realidad estamos verificando si estamos en el contenedor o no y, de ser así, ejecutamos nuestro código de configuración. Esto funciona, pero me gustaría saber si hay una mejor manera.
Algunos fragmentos de nuestro código (ignore la simplicidad del código y el hecho de que el método setupComponents realmente no es necesario aquí, hay pruebas mucho más complicadas que estamos migrando que necesitarán esta funcionalidad):
public class BaseTest extends Arquillian
{
private static Log log = LogFactory.getLog(SeamTest.class);
@Deployment
public static Archive<?> createDeployment()
{
// snip... basically, we create a test war here
}
/**
* todo - there might be a better way to do this
*/
private boolean runningInContainer()
{
try
{
new InitialContext().lookup("java:comp/env");
return true;
}
catch (NamingException ex)
{
return false;
}
}
@BeforeClass
public void setupOnce() throws Exception
{
getLog().debug("in setupOnce(): " + runningInContainer());
if (runningInContainer())
{
new ComponentTest()
{
protected void testComponents() throws Exception
{
setupComponents();
}
}.run();
}
}
public User createUser()
{
// ...
}
public Log getLog()
{
// snip...
}
public UserDao getUserDao()
{
// ...
}
public abstract class ComponentTest
{
protected abstract void testComponents() throws Exception;
public void run() throws Exception
{
try {
testComponents();
} finally {
}
}
}
}
public class UserDaoTest extends BaseTest
{
UserDao userDao;
@Override
protected void setupComponents()
{
getLog().debug("in setupComponents: " + runningInContainer());
userDao = getUserDao();
}
@Test
public void testGetUser() throws Exception
{
getLog().debug("in testGetUser: " + runningInContainer());
new ComponentTest()
{
protected void testComponents() throws Exception
{
User user0 = createUser();
user0.setName("frank");
userDao.merge(user0);
User retrievedUser = userDao.findByName("frank");
assertNotNull(retrievedUser);
}
}.run();
}
}
esto básicamente me da salida que se parece a esto:
Desde la consola donde se ejecuta mvn:
in setupOnce(): false
Desde el servidor jboss:
in setupOnce(): true
in setupComponents: true
in testGetUser: true
A partir de ahora, '@ BeforeClass' está pensado para funcionar sólo en el cliente para las pruebas Arquillian. Pero esto parece un error. ¿Podría actualizar esta pregunta con su código? Nota: [ARQ-351] (https://issues.jboss.org/browse/ARQ-351) traerá el control para la ejecución de los eventos del ciclo de vida. –
@VineetReynolds, el código es muy simple. Publicaré un fragmento. Si el comportamiento esperado en el futuro es tener solo "@BeforeClass" fuera del contenedor, ¿cómo puedo anotar un método que hará que se ejecute en el contenedor pero antes de todas las pruebas de esa clase? –
Además, @VineetReynolds, si desea publicar una respuesta en lugar de su comentario e incluir una solución alternativa para que pueda obtener crédito, hágalo. –