2013-02-12 3 views
4

в моих тестах Мне нужно использовать пружинные зависимости, связанные с транзакциями и параметрами. Я нашел пример, как использовать параметризованные и DI:Как создать весенний параметризированный транзакционный тест

@RunWith(value = Parameterized.class) 
@ContextConfiguration(locations = { "classpath:applicationContextTest-business.xml" }) 
public class TournamentServiceTest { 

@Autowired 
TournamentService tournamentService; 

    public TournamentServiceTest(int playerCount) { 
     this.playerCount = playerCount; 
    } 

    @Parameters 
    public static List<Object[]> data() { 
     final List<Object[]> parametry = new ArrayList<Object[]>(); 
     parametry.add(new Object[] { 19 }); 
     parametry.add(new Object[] { 20 }); 
     return parametry; 
    } 

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

@Test 
public void test1() { 
    Assert.assertFalse(false); 
} 

} 

этот пример работает. Теперь мне нужно добавить транзакцию к этому классу:

@RunWith(value = Parameterized.class) 
@ContextConfiguration(locations = { "classpath:applicationContextTest-business.xml" }) 
@Transactional 
@TransactionConfiguration(defaultRollback = true) 
public class TournamentServiceTest ... 

, когда я добавить две новые линии, то этот тест выброшенное исключение:

org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.toursys.processor.service.TournamentServiceTest]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given 

, потому что он хочет, чтобы добавить пустой конструктор:

public TournamentServiceTest() { 
    this.playerCount = 20; 
} 

, но я не могу добавить это, потому что тогда параметризованный не может запустить этот тест. Как я могу решить эту проблему?

ответ

2

Spring TestContext Framework в настоящее время not support Parameterized tests. Для этого вам нужно собственное правило или бегун. Существует открытый pull request, вы можете взять код оттуда.

С весны 4.2 вы можете использовать

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

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

hm thx, то я изменил концепцию моего теста. Я пропускаю аннотацию Transactional, а в аннотации After я удаляю все, что я изменил или создал в тесте – hudi

0

У меня есть этот JUnit-бегун CallbackParams - http://callbackparams.org

Это обеспечивает параметризацию, но он также может передавать фактический тест-исполнение в JUnit -раннера по вашему выбору. Если перейти к SpringJUnit4ClassRunner вы получите «пружинный параметризированный транзакционной тест», с поддержкой транзакций и т.д. ...

@RunWith(CallbackParamsRunner.class) 
@WrappedRunner(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:applicationContextTest-business.xml"}) 
@Transactional 
@TransactionConfiguration(defaultRollback = true) 
public class TestTournamentService { 

    enum PlayerCountData { 
     _19, _20; 

     final int value = Integer.parseInt(name().substring(1)); 
    } 

    @ParameterizedValue PlayerCountData playerCount; 

    @Autowired TournamentService tournamentService; 

    @Test 
    public void test1() { 
     Assert.assertNotNull(
       "TournamentService should have been autowired", 
       tournamentService); 
     Assert.assertTrue("Player-count value greater than 18", 
       18 < playerCount.value); 
     Assert.assertTrue("Player-count value less than 21", 
       playerCount.value < 21); 
    } 
} 

Как вы можете видеть решение параметризации немного отличается. Это происходит потому, что CallbackParams не дает приоритет параметризации примитивных данных, из-за причин, которые объясняются в учебниках: http://callbackparams.org/index.html#articles

С CallbackParams Параметр-значения определяются из параметра типа, поэтому INT не может быть использована parameterers непосредственно. - В приведенном выше примере используется параметр PlayerCountData параметра-типа и анализируется значения int из имен enum-констант.

Запуск результаты испытаний класса в двух тестовых прогонов с этими именами:

  • test1 [playerCount = _19]
  • test1 [playerCount = _20]

Может быть, это то, что ты ищешь.

Смежные вопросы