2010-03-23 66 views
9

有没有办法让一个扩展AbstractTransactionalJUnit4SpringContexts的类与JUnit自己的@RunWith(Parameterized.class)一起使用,以便标记为Autowired的字段能够正确连线?春天交易参数化测试和自动装配

@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

是什么'AbstractTransactionalJUnit4SpringContexts'? – Bozho 2010-03-23 19:17:48

+0

对不起,这是一个错字。现在应该修复,以及参数化的“.class”。 – 2010-03-23 19:19:43

回答

5

请参阅http://jira.springframework.org/browse/SPR-5292 有一个解决方案。

+0

不错!谢谢,这将是一个巨大的帮助。 – 2010-06-04 19:28:26

+0

我已经使用这个解决方案。要小心,他们定义自己的参数注释。当代码调用getParametersMethod(final TestClass testClass)时,则testClass.getAnnotatedMethods(Parameters.class);将返回并清空列表。当你删除 public static @interface Parameters {}它开始按预期工作... – uthomas 2011-08-19 06:45:17

1

不,你不能。这个超类有:

@RunWith(SpringJUnit4ClassRunner.class) 

它确保测试在春天的环境下运行。如果你更换它,你会失去这个。

作为一种替代方法,我想到的是扩展SpringJunit4ClassRunner,在那里提供您的自定义功能并将其与@RunWith(..)一起使用。因此,您将拥有春季环境+您的附加功能。它会呼叫super.createTest(..),然后在测试中执行其他内容。

+0

这是令人失望的......无论如何感谢。 – 2010-03-23 19:43:08

+1

@詹姆斯金斯伯里看到我的更新 – Bozho 2010-03-23 19:47:22

+0

是的,我得出了相同的结论(当然是一个好主意)。 – 2010-03-23 21:28:41

4

您可以使用Spring的TestContextManager。在这个例子中,我使用的是Theories而不是Parameterized。

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

我发现这个解决方案在这里:How to do Parameterized/Theories tests with Spring

+1

这个选项不会支持像@BeforeTransaction这样的事情吗? – 2010-09-28 13:32:21

0

由西蒙的解决方案的启发,你可以使用TestContextManager来也与参数亚军:

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

} 

这里是full example

我不知道关于在这种情况下处理@Transactional。

+2

我测试过@Transactional注解不是由TestContextManager处理 – 2011-01-26 15:29:49

0

我不得不处理的交易程序(见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

您可以使用SpringClassRuleSpringMethodRule为此目的

@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 
    } 
} 
相关问题