我正在使用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如何工作是人们所期待的。
我通过TestRule创建了一个定制的ExternalResource,如下所示:
@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总是被忽略,这意味着被CompleteRule覆盖的ExternalResource.before方法永远不会被执行。
我试过用
@Rule
public TestRule chain = RuleChain.outerRule(SPRING_CLASS_RULE)
.around(completeRule);也不起作用。即使是最糟糕的情况也不可能添加SpringMethodRule,因为它实现了MethodRule而不是TestRule,这是around方法所要求的。
我希望避免使用hierarchy,转而使用Rules。因为这是最好的做法。
因此:是否有办法解决这一问题?
Note我在其他文章中发现了一个建议是如何创建@Rule和嵌套其他规则的。遗憾的是,没有关于这种方法的样本来测试它。
Note是围绕@RunWith(Parameterized.class)进行的非常重要的工作,因为是强制性的使用,@Parameters(name="{index}: ''{0}''")和SpringClassRule和SpringMethodRule都是为此而设计的,符合它们的API。
发布于 2018-03-12 15:12:44
JUnit 4
您所描述的场景实际上是在https://jira.spring.io/browse/SPR-15927中描述的。
如果Spring也通过规则(例如,通过TestRule和SpringMethodRule)进行配置,那么在Spring之前注入自定义的JUnit是不可能的。
实际上,自定义的TestRule字段将在Spring之前被注入,但在游戏中已经太晚了。
换句话说,当使用Spring规则执行依赖项注入时,当前Runner将不会注意到注入的自定义TestRule存在,因为在规则检测阶段该字段以前是null。
这基本上是一个“鸡与蛋”的问题,而且JUnit 4没有内置的解决方法。
但是,您可以通过要求Spring对现有规则执行依赖注入来实现类似的目标,但这需要自定义代码。详情请参见SPR-10252。
JUnit木星(JUnit 5)
使用JUnit木星5.1,这实际上应该更容易实现。也就是说,您可以将参数化测试支持与Spring结合在一起,而不会出现任何问题。
JUnit木星的诀窍是确保您在类级别注册SpringExtension (例如,通过@ExtendWith、@SpringJUnitConfig或类似的)。然后,您可以在字段中使用@RegisterExtension和@Autowired,将Spring管理的扩展注入到测试实例中,并由JUnit木星使用。
https://stackoverflow.com/questions/49238290
复制相似问题