2010-03-23 2 views
9

Есть ли способ получить класс, который расширяет AbstractTransactionalJUnit4SpringContexts, чтобы хорошо играть с JUnit собственным @RunWith (Parameterized.class), чтобы поля, отмеченные как Autowired, правильно подключались?Spring Transactional Parameterized Test and Autowiring

@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

+0

К сожалению, это была опечатка. Должно быть исправлено сейчас, а также «.class» в параметризованных. –

ответ

5

См. http://jira.springframework.org/browse/SPR-5292 Существует решение.

+0

Ницца! Спасибо, это будет огромной помощью. –

+0

Я использовал это решение. Будьте осторожны, они определяют свою собственную аннотацию параметров. Когда код вызывает getParametersMethod (final TestClass testClass), тогда testClass.getAnnotatedMethods (Parameters.class); вернет и опустит список. Когда вы удаляете public static @interface Parameters {}, он начинает работать как ожидалось ... – uthomas

1

Нет, вы не можете. В суперклассе есть:

@RunWith(SpringJUnit4ClassRunner.class) 

, который гарантирует, что тесты выполняются в контексте весны. Если вы его замените, вы потеряете это.

Что приходит мне на ум в качестве альтернативы для расширения SpringJunit4ClassRunner, предоставьте свои пользовательские функции там и используйте его с помощью @RunWith(..). Таким образом, у вас будет весенний контекст + ваши дополнительные функции. Он назовет super.createTest(..), а затем выполнит дополнительные тесты.

+0

Это неутешительно ... спасибо в любом случае. –

+1

@James Kingsbery см. Мое обновление для альтернативы – Bozho

+0

Да, я пришел к такому же выводу (должно быть, это хорошая идея). –

4

Вы можете использовать TestContextManager с Spring. В этом примере я использую Теории вместо 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, не так ли? –

0

Вдохновленный решения Саймона, вы можете использовать TestContextManager также с Parameterized бегуна:

@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 –

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

Вы можете использовать SpringClassRule и SpringMethodRule для этой цели

@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 
    } 
} 
Смежные вопросы