2010-03-23 5 views
9

Existe-t-il un moyen d'obtenir une classe qui étend AbstractTransactionalJUnit4SpringContexts pour bien jouer avec @RunWith (Parameterized.class) de JUnit, de sorte que les champs marqués Autowired soient correctement câblés?Test paramétré transactionnel de ressort et auto-traitement

@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

ce qui est 'AbstractTransactionalJUnit4SpringContexts'? – Bozho

+0

Désolé, c'était une faute de frappe. Devrait être réparé maintenant, ainsi que le ".class" sur Parameterized. –

Répondre

5
+0

Nice! Merci, ça va être une aide énorme. –

+0

J'ai utilisé cette solution. Attention, ils définissent leur propre annotation de paramètres. Lorsque le code appelle getParametersMethod (final TestClass testClass), alors testClass.getAnnotatedMethods (Parameters.class); retournera et videra la liste. Lorsque vous supprimez public static @interface Paramètres {} il commence à fonctionner comme prévu ... – uthomas

1

Non, vous ne pouvez pas. La superclasse a:

@RunWith(SpringJUnit4ClassRunner.class) 

ce qui garantit que les tests sont exécutés dans un contexte de printemps. Si vous le remplacez, vous perdez ceci. Ce qui me vient à l'esprit est de prolonger SpringJunit4ClassRunner, de fournir votre fonctionnalité personnalisée et de l'utiliser avec @RunWith(..). Ainsi vous aurez le contexte printanier + vos fonctionnalités supplémentaires. Il appellera super.createTest(..), puis effectuera des tâches supplémentaires sur le test.

+0

C'est décevant ... merci quand même. –

+1

@ James Kingsbery voir ma mise à jour pour une alternative – Bozho

+0

Ouais, je suis arrivé à la même conclusion (doit être une bonne idée alors). –

4

Vous pouvez utiliser un TestContextManager de Spring. Dans cet exemple, j'utilise des théories au lieu de paramétrer.

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

J'ai trouvé cette solution ici: How to do Parameterized/Theories tests with Spring

+1

cette option ne prendrait pas en charge des choses comme @BeforeTransaction, n'est-ce pas? –

0

Inspiré par la solution de Simon, vous pouvez utiliser TestContextManager aussi avec runner paramétrées:

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

} 

Voici full example

Je ne suis pas sûr à propos de la gestion de @Transactional dans ce cas.

+2

J'ai testé que les annotations @Transactional ne sont pas gérées par TestContextManager –

0

J'ai dû gérer les transactions par programme (voir 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

Vous pouvez utiliser SpringClassRule et SpringMethodRule à cet effet

@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 
    } 
} 
Questions connexes