Java 如何正确配置@RunWith(Parameterized.class)和#x2B;SpringClassRule+;SpringMethodRule与自定义@Rule?
我正在使用Java 如何正确配置@RunWith(Parameterized.class)和#x2B;SpringClassRule+;SpringMethodRule与自定义@Rule?,java,spring,junit,spring-test,junit5,Java,Spring,Junit,Spring Test,Junit5,我正在使用springframework4.3.x和JUnit4,我有以下结构 @Transactional @WebAppConfiguration @RunWith(Parameterized.class) @ContextConfiguration(classes={RootApplicationContext.class, ServletApplicationContext.class}) @TestExecutionListeners(listeners={LoggingTestExe
springframework
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
方法被覆盖
通过完成规则
永远不会执行
我试过使用
@Rule
public TestRule chain = RuleChain.outerRule(SPRING_CLASS_RULE)
.around(completeRule);
而且不起作用。即使是最坏的情况也不可能添加SpringMethodRule
,因为它实现了MethodRule
而不是TestRule
方法要求的方式
我希望避免使用层次结构
,而是使用规则
。这是因为这是一种最佳实践
因此:有没有办法解决这个问题
注意我在其他帖子中找到了建议如何创建@Rule
和嵌套其他规则。遗憾的是,没有关于这种方法的样本来测试它
注意是解决@RunWith(Parameterized.class)
的非常重要的工作,因为必须使用@Parameters(name=“{index}:”“{0}””)
和SpringClassRule
和SpringMethodRule
是根据它们的API为此而设计的
SpringClassRule
和SpringMethodRule
),那么Spring注入的定制TestRule
不可能被JUnit实际作为规则获取
定制的TestRule
字段实际上将由Spring注入,但在游戏中已经太晚了
换句话说,当Spring规则用于执行依赖项注入时,当前的运行程序将不会注意到注入的自定义TestRule
存在,因为在规则检测阶段该字段以前是null
这基本上是一个“鸡和蛋”的问题,JUnit4没有内置的解决方法
然而,您可以通过要求Spring对现有规则执行依赖项注入来实现类似的功能,但这需要自定义代码。有关详细信息,请参阅
JUnit Jupiter(JUnit 5)
使用JUnitJupiter 5.1,这实际上应该更容易实现。也就是说,您可以将参数化测试支持与Spring结合起来,而不会出现任何问题
JUnit Jupiter的诀窍是确保在类级别注册SpringExtension
(例如,通过@ExtendWith
、@SpringJUnitConfig
或类似方式)。然后,您可以在一个字段上使用@RegisterExtension
和@Autowired
,将一个Spring管理的扩展注入到测试实例中,供JUnit Jupiter使用。感谢有价值的解释,因此我将使用JUnit
5。你还记得我在Github中创建一个关于JUnit5的问题吗?我在那里分享了一些关于我自己的迁移实验的代码,对于“参数化的”
,不再需要使用SpringClassRule
和SpringMethodRule
。现在,如果我的内存没有问题,TestRule在JUnit5中就不再存在了。