Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.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 合并来自不同声明的多个@TestExecutionListener?_Java_Spring_Spring Boot_Spring Test_Spring Boot Test - Fatal编程技术网

Java 合并来自不同声明的多个@TestExecutionListener?

Java 合并来自不同声明的多个@TestExecutionListener?,java,spring,spring-boot,spring-test,spring-boot-test,Java,Spring,Spring Boot,Spring Test,Spring Boot Test,对于我的SpringBoot应用程序的集成测试,我声明了自定义元注释(有点像SpringBoot的测试片注释)。如何在每个元注释中声明不同的TestExecutionListener,并在运行测试类时将它们合并 我只能找到mergeMode=MERGE_WITH_DEFAULTS,它将声明的TestExecutionListener与默认的Listener合并,但不能在不同的位置声明不同的自定义侦听器 一个简单的例子: @Target(ElementType.TYPE) @Retention(R

对于我的SpringBoot应用程序的集成测试,我声明了自定义元注释(有点像SpringBoot的测试片注释)。如何在每个元注释中声明不同的TestExecutionListener,并在运行测试类时将它们合并

我只能找到
mergeMode=MERGE_WITH_DEFAULTS
,它将声明的TestExecutionListener与默认的Listener合并,但不能在不同的位置声明不同的自定义侦听器

一个简单的例子:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@TestExecutionListeners(
  listeners = DbTestListener.class,
  mergeMode = MERGE_WITH_DEFAULTS)
public @interface DbIntegrationTest {
}


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@TestExecutionListeners(
  listeners = MessagingTestListener.class,
  mergeMode = MERGE_WITH_DEFAULTS)
public @interface MessagingIntegrationTest {
}


@RunWith(SpringRunner.class)
@DbIntegrationTest
@MessagingIntegrationTest
public class ExampleTest {
  // test cases here
}
因此,我希望为我的
ExampleTest
执行定制的TestListener和默认的TestListener


澄清:上面的例子是最小的,以显示我想要什么。当然,这样做没有多大意义。我自己编写的注释中有很多我没有展示的设置,我有多层元注释。

这些侦听器做什么?若提供了执行环境,那个么您就误用了侦听器API

要配置(和清理)环境,您应该使用

  • @Rule
    \
    @ClassRule
    如果使用Junit4
  • @ExtendWith
    如果使用Junit5

这些功能很容易在单个测试中组合。

当前版本的spring测试中没有此类功能

如果你更深入地思考你的想法,在某些情况下会引入模棱两可的概念。例如,如果
@DbIntegrationTest
@messaginintegrationtest
配置了不同的
合并模式
继承侦听器
,框架应该使用哪个值

当前的行为是,如果有多个
@TestExecutionListeners
或其元注释被标记,则只有最前面声明的一个将生效,而另一个将被忽略

一些可能帮助您实现类似结果的想法:

  • 使用元注释预定义某种配置文件,该配置文件将多个
    TestExecutionListeners
    分组,这些将在不同的测试场景中一起使用。只需将这个元注释注释到测试类。例如:
  • @MessagingTest
    包含消息传递集成测试所需的所有侦听器:

    @TestExecutionListeners(
    侦听器={SetupMessageBrokerListener.class,FooBarListener.class},
    mergeMode=将\u与\u默认值合并)
    公共@interface MessagingTest{
    }
    
    @DatabaseTest
    包含DB集成测试所需的所有侦听器:

    @TestExecutionListeners(
    侦听器={SetupDatabaseListener.class,CreateTestingDataListener.class,FooBarListener.class},
    mergeMode=将\u与\u默认值合并)
    public@interface数据库测试{
    }
    
  • 实现自己版本的
    TestContextBootstrapper
    。要创建的
    TestExecutionListener
    在其
    getTestExecutionListeners()
    中定义。使用
    @BootstrapWith
    激活此
    TestContextBootstrapper
    <代码>AbstractTestContextBootstrapper是一个很好的起点。基本上,您需要在
    getTestExecutionListeners()
    的末尾添加自定义逻辑。遗憾的是,此方法已完成,不允许在子类中重写

  • 一种可能的解决方案是在META-INF/spring.Factorys中注册所有TestExecutionListeners,并编写每个侦听器,以便仅当测试类或测试上下文中存在某个注释(或其他标记)时,它才执行某些操作

    有关spring.factories的用法,请参见:


    此解决方案的缺点是TestExecutionListeners(已定义且将处于活动状态)的设置有点“隐藏”或分散在代码库中。

    它们对测试环境进行准备和/或后处理。DbListener(例如)在每次测试前清除数据库。它们是Spring的测试框架独立测试支持的一个组成部分,请参见:至于为什么不使用例如
    @Rule
    :正如我在示例中所示,
    @TestExecutionListeners
    注释可以用作元注释(即在组合注释中)。使用
    @Rule
    等,我必须将规则添加到每个测试类中。使用我的
    @DbIntegrationTest
    组合注释,我可以将该注释放在类的顶部,然后从那里处理所有事情(测试设置的内聚性)。此外,Spring TestExecutionListeners可以访问Spring的测试上下文,这可能很有用。老实说,我看不出
    @ClassRule
    和元注释在您的情况下有什么区别:元注释应该在每个测试中添加一次(“在我的类的顶部”),而
    @ClassRule
    应该在每个测试中添加一次(“我必须将规则添加到每个测试类中”)。无论如何,我只能建议您尝试最新的Spring框架-可能是他们改进了它,如果他们没有改进,那么您可以在他们的Github中归档错误。或者,您可以为每个有意义的侦听器组合创建元注释,即
    @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@TestExecutionListeners(listeners={DbTestListener.class,MessagingTestListener.class},mergeMode=MERGE_WITH_DEFAULTS)public@interface Database和MessagingIntegrationTest{}
    很好的尝试,应该可以。在这种情况下,您必须重写
    GetDefaultTestExecutionListenerClass()
    DefaultTestContextBootstrapper的
    ,并将这些逻辑添加到其中。不,实际上我认为标准引导程序已经做到了。Spring文档明确地说:第三方框架和开发人员可以通过自己的META-INF/spring.factories属性文件,以同样的方式将自己的TestExecutionListener实现贡献给默认侦听器列表