2010-08-04 10 views
14

Estoy usando Spring para inyectar la ruta a un directorio en mis pruebas unitarias. Dentro de este directorio hay una cantidad de archivos que se deben usar para generar datos de prueba para casos de prueba parametrizados usando el corredor de prueba Parameterized. Desafortunadamente, el corredor de prueba requiere que el método que proporciona los parámetros sea estático. Esto no funciona para mi situación porque el directorio solo se puede inyectar en un campo no estático. ¿Alguna idea de cómo puedo evitar esto?¿Cómo puedo usar el corredor de prueba JUnit parametrizado con un campo que se inyecta usando Spring?

+2

puede cambiar a otro mecanismo para inyectar una cadena en una prueba de fijación? Me refiero a que el cuello de botella aquí parece ser que Spring no puede establecer campos no estáticos/ – Gishu

+0

Gishu: establece campos estáticos, ¿no? Tal vez no en JUnit porque la orden o ejecución tendría el método @Parameters llamado antes de Spring. ¿Pero en general? –

+0

Relacionados: https://stackoverflow.com/questions/28560734/how-to-run-junit-springjunit4classrunner-with-parametrized – tkruse

Respuesta

6

Asumo que está usando 4.X JUnit ya que ha mencionado el corredor prueba parametrizado. Esto implica que no estás usando @RunWith (SpringJUnit4ClassRunner). No es un problema, solo enumera mis suposiciones.

Lo siguiente usa Spring para obtener el directorio de archivos de prueba del archivo XML. No lo inyecta, pero los datos aún están disponibles para su prueba. Y en un método estático no menos.

La única desventaja que veo es que puede significar que su configuración de Spring se está analizando/configurando varias veces. Puede cargar solo un archivo más pequeño con información específica de prueba si es necesario.

@RunWith(Parameterized.class) 
public class MyTest { 
    @Parameters 
    public static Collection<Object[]> data() { 
     ApplicationContext ctx = new ClassPathXmlApplicationContext("/jeanne/jeanne.xml"); 
     String dir = ctx.getBean("testFilesDirectory", String.class); 

      // write java code to link files in test directory to the array 
     return Arrays.asList(new Object[][] { { 1 } }); 
    } 
// rest of test class 
} 
+0

Buena idea. Olvidé por completo acerca de obtener el 'ApplicationContext' de forma manual. Hace que el código sea un poco más feo, pero hace que la salida de prueba sea infinitamente mejor para poder usar 'Parameterized'. –

0

Recuerde que Spring se inyecta usando @Autowired, pero también con setter. Así que en lugar de utilizar @Autowired, utilice el colocador:

private static String directory; 

public void setDirectory(String directory) { 
    this.directory = directory; 
} 

public static String getDirectory() { 
    return directory; 
} 
11

Puede usar TestContextManager desde Spring. En este ejemplo, estoy usando Teorías en lugar de Parametrizadas.

@RunWith(Theories.class) 
@ContextConfiguration(locations = "classpath:/spring-context.xml") 
public class SeleniumCase { 
    @DataPoints 
    public static WebDriver[] drivers() { 
    return new WebDriver[] { firefoxDriver, internetExplorerDriver }; 
    } 

    private TestContextManager testContextManager; 

    @Autowired 
    SomethingDao dao; 

    private static FirefoxDriver firefoxDriver = new FirefoxDriver(); 
    private static InternetExplorerDriver internetExplorerDriver = new InternetExplorerDriver(); 

    @AfterClass 
    public static void tearDown() { 
    firefoxDriver.close(); 
    internetExplorerDriver.close(); 
    } 

    @Before 
    public void setUpStringContext() throws Exception { 
    testContextManager = new TestContextManager(getClass()); 
    testContextManager.prepareTestInstance(this); 
    } 

    @Theory 
    public void testWork(WebDriver driver) { 
    assertNotNull(driver); 
    assertNotNull(dao); 
    } 
} 

He encontrado esta solución aquí: How to do Parameterized/Theories tests with Spring

+0

dice que necesita etiquetar esta prueba con una anotación de Spring, como @Transactional. ¿Cómo harías eso con TestContextManager? –

3

utilizo la siguiente solución con el Parameterized.class sin ningún problema: http://bmocanu.ro/coding/320/combining-junit-theoriesparameterized-tests-with-spring/

@ContextConfiguration(value = "classpath:test-context.xml") 
public abstract class AbstractJunitTest extends AbstractJUnit4SpringContextTests { 
    private static TestContextManager testContextManager = null; 
    private static DAOFactory daoFactory = null; 

    @Before 
    public void initApplicationContext() throws Exception { 
     if (testContextManager == null) { 
      testContextManager = new TestContextManager(getClass()); 
      testContextManager.prepareTestInstance(this); 
      daoFactory = (DAOFactory)applicationContext.getBean("daoFactory"); 
     } 
    } 

    protected DAOFactory getDaoFactory() throws Exception { 
     return daoFactory; 
    } 
} 



@RunWith(Parameterized.class) 
public class SomeTestClass extends AbstractJunitTest { 
    ... 
} 
4

Es suficiente para anotar clase de prueba con @RunWith(Parameterized.class) y @ContextConfiguration, use @Autowired para la inyección de dependencia y use TestContextManager en el constructor para la inicialización, p. Ej .:

@RunWith(Parameterized.class) 
@ContextConfiguration(classes = TestConfig.class) 
public class MyTest { 

    @Autowired 
    private DataSource dataSource; 

    private final int param; 

    @Parameterized.Parameters 
    public static List<Object[]> params() { 
     return Arrays.asList(new Object[][]{ 
      {1}, 
      {2}, 
     }); 
    } 

    public MyTest(int p) { 
     this.param = p; 
     new TestContextManager(getClass()).prepareTestInstance(this); 
    } 

    @Test 
    public void testSomething() { 
     … 
    } 
} 
+0

Como advertencia, recuerde que no puede usar beans inyectados (dataSource en este ejemplo) como fuente de parámetro. El método @ Parameterized.Parameters debe ser estático. –

3

Para alguien leyendo esto tarde o temprano 2015, ha Spring 4.2, además de SpringJUnit4ClassRunner añadido SpringClassRule y SpringMethodRule que aprovechan el apoyo a Spring TestContext Framework.

Esto significa soporte de primera clase para cualquier corredor o como MockitoJUnitRunnerParameterized:

@RunWith(Parameterized.class) 
public class FibonacciTest { 
    @ClassRule public static final SpringClassRule SCR = new SpringClassRule(); 
    @Rule public final SpringMethodRule springMethodRule = new SpringMethodRule(); 

    long input; 
    long output; 

    public FibonacciTest(long input, long output) { this.input = input; ...} 

    @Test 
    public void testFibonacci() { 
     Assert.assertEquals(output, fibonacci(input)); 
    } 

    public List<Long[]> params() { 
     return Arrays.asList(new Long[][] { {0, 0}, {1, 1} }); 
    } 
} 
Cuestiones relacionadas