4

在我的测试中,我需要使用 spring 依赖注入事务和参数。我找到了如何使用参数化和 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;
}

但我不能添加这个,因为然后参数化不能运行这个测试。我该如何解决这个问题?

4

2 回答 2

2

Spring TestContext 框架当前不支持参数化测试。为此,您需要一个自定义规则或运行器。有一个 open pull request,您可以从那里获取代码。

从 Spring 4.2开始,您可以使用

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

@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
于 2013-02-12T15:23:38.270 回答
0

我有这个 CallbackParams 的 JUnit-runner - http://callbackparams.org

它提供参数化,但它也可以将实际的测试执行传递给您选择的 JUnit-runner。如果您传递给 SpringJUnit4ClassRunner,您将获得“spring 参数化事务测试”,以及事务支持等......

@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 参数器。- 上面的示例使用参数类型 PlayerCountData 并从枚举常量的名称中解析 int 值。

运行测试类会产生两个具有以下名称的测试运行:

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

也许这就是你要找的。

于 2013-05-08T13:06:48.320 回答