Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何正确配置@RunWith(Parameterized.class)和#x2B;SpringClassRule+;SpringMethodRule与自定义@Rule?_Java_Spring_Junit_Spring Test_Junit5 - Fatal编程技术网

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为此而设计的

JUnit 4 您所描述的场景实际上包含在中

如果Spring也是通过规则配置的(例如,通过
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中就不再存在了。