gpt4 book ai didi

java - 如何使用自定义@Rule正确配置@RunWith(Parameterized.class) + SpringClassRule + SpringMethodRule?

转载 作者:行者123 更新时间:2023-12-01 21:57:55 25 4
gpt4 key购买 nike

我正在使用 Spring Framework 4.3.x 和 JUnit 4,我有以下结构

@Transactional
@WebAppConfiguration
@RunWith(Parameterized.class)
@ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})
@TestExecutionListeners(listeners={LoggingTestExecutionListener.class}, mergeMode=MergeMode.MERGE_WITH_DEFAULTS)
public class CompleteTest {

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

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

因此组合:

  • @RunWith(Parameterized.class) + SpringClassRule + SpringMethodRule

按预期工作。

我通过 ExternalResource 创建了一个自定义 TestRule,如下所示:

@Component
public class CompleteRule extends ExternalResource {

private static final Logger logger = LoggerFactory.getLogger(CompleteRule.class.getSimpleName());

private final WebApplicationContext webApplicationContext;

private final Environment environment;

private MockMvc mockMvc;

public CompleteRule(WebApplicationContext webApplicationContext, Environment environment) {
this.webApplicationContext = webApplicationContext;
this.environment = environment;
}

@Override
protected void before() throws Throwable {
...
}

因此,如果我尝试然后使用:

@Transactional
@WebAppConfiguration
@RunWith(Parameterized.class)
@ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class})
@TestExecutionListeners(listeners={LoggingTestExecutionListener.class}, mergeMode=MergeMode.MERGE_WITH_DEFAULTS)
public class CompleteTest {

private static final Logger logger = LoggerFactory.getLogger(CompleteTest.class.getSimpleName());

@Rule
@Autowired
public CompleteRule completeRule;

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

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

CompleteRule 始终被忽略,这意味着 ExternalResource.before 方法被覆盖by CompleteRule 永远不会执行。

我尝试过使用

@Rule
public TestRule chain = RuleChain.outerRule(SPRING_CLASS_RULE)
.around(completeRule);

并且不起作用。最糟糕的是不可能添加SpringMethodRule,因为它实现了MethodRule,而不是around方法所要求的TestRule

我想避免使用层次结构并使用规则来解决。因为这是最佳实践。

因此:有没有办法解决这个问题?

注意我在其他帖子中发现建议如何创建@Rule并嵌套其他规则。遗憾的是没有关于这种方法的示例来测试它。

注意对于@RunWith(Parameterized.class)非常重要,因为强制使用@Parameters(name="{index}: ''{ 0}''")SpringClassRuleSpringMethodRule 是根据其 API 为此设计的。

最佳答案

JUnit 4

您所描述的场景实际上包含在 SPR-15927 中.

如果 Spring 也是通过规则配置的(例如,通过 SpringClassRuleSpringMethodRule)。

自定义 TestRule 字段实际上将由 Spring 注入(inject),但为时已晚。

换句话来说,当使用 Spring 规则执行依赖注入(inject)时,当前的 Runner 不会注意到注入(inject)的自定义 TestRule 存在,因为该字段之前在规则检测阶段为 null

这基本上是一个“先有鸡还是先有蛋”的问题,JUnit 4 没有内置的解决方法。

但是,您可以通过要求 Spring 对现有规则执行依赖注入(inject)来实现类似的效果,但这需要自定义代码。请参阅SPR-10252了解详情。

JUnit Jupiter (JUnit 5)

使用 JUnit Jupiter 5.1,这实际上应该更容易实现。也就是说,您可以毫无问题地将参数化测试支持与 Spring 结合起来。

JUnit Jupiter 的技巧是确保在类级别注册 SpringExtension(例如,通过 @ExtendWith@SpringJUnitConfig ,或类似)。然后,您可以在字段上使用 @RegisterExtension@Autowired 将 Spring 管理的扩展注入(inject)到 JUnit Jupiter 使用的测试实例中.

关于java - 如何使用自定义@Rule正确配置@RunWith(Parameterized.class) + SpringClassRule + SpringMethodRule?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49238290/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com