当前位置: 首页 > 知识库问答 >
问题:

JUnit 5:将Spring组件注入扩展(BeforeAllCallback/AfterAllCallback)

慕志泽
2023-03-14

如何在所有测试运行之前将自定义数据提供程序实例化为Spring组件?

有没有一种聪明的方法将Spring组件注入到一个定制的JUnit Jupiter扩展中,该扩展在回调之前实现beforeAll方法应该在使用@extendedwith(OncePerTestRunExtension.class)执行MyTestClass之前触发一个复杂的进程。

我创建了一个Spring启动应用程序(src/main/java),它为我的测试(src/test/java)提供了必要的数据。为测试准备数据可能需要几个小时。它还为我提供了对一些restendpoint的抽象访问。

在所有测试类的进程之间,数据不会发生变化。所以我只想提取一次数据。

在一个类中编写所有的测试是可行的,但是我认为将测试分为不同的类可以提供更好的概述。

共有2个答案

柏高丽
2023-03-14

下面是我如何实现这一点,使用dataSourcespringbean在我的数据库中设置一些测试数据,方法是将上面Sam的答案与下面的答案结合起来:https://stackoverflow.com/a/51556718/278800

import javax.sql.DataSource;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit.jupiter.SpringExtension;

public class TestDataSetup implements BeforeAllCallback, ExtensionContext.Store.CloseableResource {

  private static boolean started = false;

  private DataSource dataSource;

  @Override
  public void beforeAll(ExtensionContext extensionContext) {
    synchronized (TestDataSetup.class) {
      if (!started) {
        started = true;

        // get the dataSource bean from the spring context
        ApplicationContext springContext = SpringExtension.getApplicationContext(extensionContext);
        this.dataSource = springContext.getBean(DataSource.class);

        // TODO: put your one-time db initialization code here

        // register a callback hook for when the root test context is shut down
        extensionContext
            .getRoot()
            .getStore(ExtensionContext.Namespace.GLOBAL)
            .put("TestDataSetup-started", this);
      }
    }
  }

  @Override
  public void close() {
    synchronized (TestDataSetup.class) {
      // TODO: put your db cleanup code here
    }
  }

(我不能100%确定这个线程的安全性,所以我添加了synchronized块只是为了安全。)

要启用这个扩展,您只需要将这个注释添加到需要它的测试类中:

@ExtendWith(TestDataSetup.class)

好的方面是JUnit5允许多个扩展,因此即使您的测试已经用@extendedwith(SpringExtension.class)进行了注释,它也可以工作。

赫连法
2023-03-14

在自定义beforeAll回调的beforeAll(ExtensionContext)方法中,您可以通过SpringExtension访问当前测试类的SpringApplicationContext。getApplicationContext(extensionContext)

如果您将自定义数据提供程序配置为该Application ationContext中的Spring组件,那么您可以从扩展中的Application ationContext中检索该组件-例如,通过Application ationContext.getBean(MyDataProvider.class).

如果需要处理数据并在测试之间存储处理后的数据,可以将其存储在rootExtensionContext中。在JUnit Jupiter中存储。请参阅扩展上下文。getRoot()getorComputeFabSent(…) 变体。有关详细信息,请存储

 类似资料:
  • 我有以下类 : 我想按如下方式使用它: 因此,通过扩展已经注入依赖项的超类,我希望在其子类中访问它。 我尝试了许多不同的方法,甚至将超类作为组件: 但是,<code>仍然是这样。fetchApi为,即使在超类中也是如此。

  • 问题内容: 我最欣赏Backbone.js的一件事是简单而优雅的继承是如何工作的。我开始着手处理React,并且在React中无法真正找到类似于此Backbone代码的任何内容 在react中,我们有mixin,如果使用mixin,我们可以像上面的例子那样有点接近 与一遍又一遍地定义相同的东西相比,这没有那么重复,但是它似乎不像Backbone那样灵活。例如,如果我尝试重新定义/覆盖存在于我的一个

  • 扩展 Web 组件 Vue.js 是一个独立的前端框架,在浏览器中渲染时不需要基于 Weex 容器。因此,针对 Weex 平台扩展 Vue.js 的 Web 端组件,和直接使用 Vue.js 开发一个 Web 组件是一样的。具体的组件编写方法可以参考其官方文档:组件 ,另外建议使用 .vue 格式的文件编写组件,使用方法参考:单文件组件。 扩展内置组件 目前我们提供了 Vue Render For

  • 问题内容: 我必须在Web应用程序中使用3个不同的事务管理器。因此,我根据Spring参考(第10.5.6.3节“自定义快捷方式注释”)编写了自己的注释。 一个注释(用于使用一个特定的transactionmanager)如下所示: 使用自定义的@CustomerTX批注对我的服务层进行批注时,一切工作正常。但是我必须为注释提供更多选项,例如readonly = true,rollbackFor

  • 在将添加到构建中并从junit4迁移所有内容后,Gradle开始出现以下错误。 在老式运行器中所有运行都很好,但junit5测试不是。 我很好奇我是否可以在项目评估后删除这个配置,因为无论如何都添加了所有JUnit依赖项来编译代码,然后插件只是在顶部添加负载。我创建了一个项目,将所有Junit5库封装在一个人工制品中。 编辑3 我确实设法将所有木星人工制品打包到1中,以稍微缩小cp,但我的类路径仍