2010-03-23 13 views
9

¿Hay alguna manera de obtener una clase que extienda AbstractTransactionalJUnit4SpringContexts para que se reproduzca bien con @RunWith (Parameterized.class) de JUnit, para que los campos marcados como Autowired se conecten correctamente?Prueba transaccional paramétrica de primavera y autoenlace

@RunWith(Parameterized.class) 
public class Foo extends AbstractTransactionalJUnit4SpringContextTests { 

    @Autowired private Bar bar 

    @Parameters public static Collection<Object[]> data() { 
     // return parameters, following pattern in 
     // http://junit.org/apidocs/org/junit/runners/Parameterized.html 
    } 

    @Test public void someTest(){ 
     bar.baz() //NullPointerException 
    } 
} 
+0

lo que es 'AbstractTransactionalJUnit4SpringContexts'? – Bozho

+0

Lo siento, eso fue un error tipográfico. Debería arreglarse ahora, así como también la ".class" en Parameterized. –

Respuesta

5
+0

¡Agradable! Gracias, eso será de gran ayuda. –

+0

He usado esta solución. Tenga cuidado, ellos definen su propia anotación de Parámetros. Cuando el código invoca getParametersMethod (testClass testClass), entonces testClass.getAnnotatedMethods (Parameters.class); regresará y vaciará la lista. Cuando elimina public static @interface Parameters {} está comenzando a funcionar como se esperaba ... – uthomas

1

No, no puede. La superclase tiene:

@RunWith(SpringJUnit4ClassRunner.class) 

que garantiza que las pruebas se ejecuten en el contexto de primavera. Si lo reemplazas, estás perdiendo esto.

Lo que me viene a la mente como una alternativa es ampliar SpringJunit4ClassRunner, proporcionar su funcionalidad personalizada allí y usarla con @RunWith(..). Por lo tanto, tendrá el contexto de primavera + su funcionalidad adicional. Llamará al super.createTest(..) y luego realizará tareas adicionales en la prueba.

+0

Eso es decepcionante ... gracias de todos modos. –

+1

@James Kingsbery mira mi actualización para una alternativa – Bozho

+0

Sí, llegué a la misma conclusión (debe ser una buena idea entonces). –

4

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); 
    } 
} 

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

+1

esta opción no admitiría cosas como @BeforeTransaction, ¿o sí? –

0

Inspirado por la solución de Simón, se puede utilizar TestContextManager también con el corredor parametrizado:

@RunWith(Parameterized.class) 
@ContextConfiguration(locations = "classpath:/spring-context.xml") 
public class MyTestClass { 

    @Parameters public static Collection data() { 
    // return parameters, following pattern in 
    // http://junit.org/apidocs/org/junit/runners/Parameterized.html 
    } 

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

} 

Aquí es full example

No estoy seguro sobre el manejo de @Transactional en este caso.

+2

He probado que las anotaciones de @Transactional no son manejadas por TestContextManager –

0

he tenido que manejar las transacciones mediante programación (ver http://www.javathinking.com/2011/09/junit-parameterized-test-with-spring-autowiring-and-transactions/):

@RunWith(Parameterized.class) 
@ContextConfiguration(locations = "classpath*:/testContext.xml") 
public class MyTest { 

    @Autowired 
    PlatformTransactionManager transactionManager; 

    private TestContextManager testContextManager; 

    public MyTest (... parameters for test) { 
     // store parameters in instance variables 
    } 

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

    @Parameterized.Parameters 
    public static Collection<Object[]> generateData() throws Exception { 
     ArrayList list = new ArrayList(); 
     // add data for each test here 
     return list; 
    } 

    @Test 
    public void validDataShouldLoadFully() throws Exception { 
     new TransactionTemplate(transactionManager).execute(new TransactionCallback() { 
      public Object doInTransaction(TransactionStatus status) { 
       status.setRollbackOnly(); 
       try { 
        ... do cool stuff here 

       } catch (Exception e) { 
        throw new RuntimeException(e); 
       } 
       return null; 
      } 
     }); 

    } 
0

Usted puede utilizar SpringClassRuleSpringMethodRule y para este fin

@RunWith(Parameterized.class) 
@ContextConfiguration(...) 
public class FooTest { 

    @ClassRule 
    public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); 

    @Rule 
    public final SpringMethodRule springMethodRule = new SpringMethodRule(); 

    @Autowired 
    private Bar bar 

    @Parameters 
    public static Collection<Object[]> data() { 
     // return parameters, following pattern in 
     // http://junit.org/apidocs/org/junit/runners/Parameterized.html 
    } 

    @Test 
    public void someTest() { 
     bar.baz() //NullPointerException 
    } 
} 
Cuestiones relacionadas