2011-04-20 19 views
8

Soy bastante nuevo en Spring y estoy trabajando con un conjunto de pruebas de integración JUnit 4.7 para una aplicación web. Tengo una serie de casos de prueba de trabajo de la forma:JUnit corredor personalizado con contexto de aplicación Spring

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "/META-INF/spring/testContext.xml" }) 

public class myTest { 
    @Test 
    public void testCreate() { 
      //execute tests 
      .... 
    } 
} 

Mi aplicación tiene un número de dependencias externas que estoy pruebas, todos los cuales tienen granos que se inicializan a través de la carga de testContext.xml. Algunas de estas dependencias externas requieren un código personalizado para inicializar y eliminar los recursos necesarios.

En lugar de duplicar este código en cada clase de prueba que lo requiera, me gustaría encapsularlo en una ubicación común. Mi idea era crear una definición de contexto independiente, así como un corredor a medida que se extiende SpringJUnit4ClassRunner y contiene la anotación @ContextConfiguration y código personalizado relacionado, así:

import org.junit.runners.model.InitializationError; 
import org.junit.runners.model.Statement; 
import org.springframework.context.ApplicationContext; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

//load the context applicable to this runner 
@ContextConfiguration(locations = { "/META-INF/spring/testContext.xml" }) 

public class MyCustomRunner extends SpringJUnit4ClassRunner { 

    public MyCustomRunner(Class<?> clazz) throws InitializationError { 
     super(clazz);   
    } 

    @Override 
    protected Statement withBeforeClasses(Statement statement) { 
     // custom initialization code for resources loaded by testContext.xml 
       ... 

     return super.withBeforeClasses(statement); 
    } 

    @Override 
    protected Statement withAfterClasses(Statement statement) { 
     // custom cleanup code for resources loaded by testContext.xml 
       .... 

     return super.withAfterClasses(statement); 
    } 

} 

Podría entonces cada clase de prueba especifica su corredor aplicable con:

@RunWith(MyCustomRunner) 

Cuando hago esto, mis pruebas realizadas y los propios withBeforeClasses y withAfterClasses se ejecutan métodos. Sin embargo, no se proporciona applicationContext de nuevo a la clase de prueba y todas mis pruebas fallan con:

java.lang.IllegalArgumentException: No se puede cargar un ApplicationContext con un nulo 'contextLoader'. Considere anotando su clase de prueba con @ContextConfiguration.

El contexto sólo cargas correctamente si se especifica la anotación @ContextConfiguration en cada clase de prueba - Idealmente, me gustaría que esta anotación a vivir con el código del controlador de los recursos que se encarga de cargar. Lo que me lleva a mi pregunta: ¿es posible cargar información sobre el contexto de Spring desde una clase de corredor personalizada?

Respuesta

13

Puede crear una clase de prueba de base - @ContextConfiguration pueden ser heredados, así como @Before, @After, y así sucesivamente:

@ContextConfiguration(locations = { "/META-INF/spring/testContext.xml" }) 
public abstract class myBaseTest { 
    @Before 
    public void init() { 
     // custom initialization code for resources loaded by testContext.xml 
    } 

    @After 
    public void cleanup() { 
     // custom cleanup code for resources loaded by testContext.xml 
    } 
} 

@RunWith(SpringJUnit4ClassRunner.class) 
public class myTest extends myBaseTest { ... } 
+0

Meh, herencia de clases en las pruebas ..:/ ¿Existe ahora, en 2017, ¿una forma de hacer esto correctamente? – maricn

Cuestiones relacionadas