You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JUnit测试遇ExceptionInInitializerError:JavaFX Toolkit未初始化

问题:JUnit测试JavaFX相关代码时出现Toolkit未初始化异常

测试代码

@org.junit.jupiter.api.Test
void createReservation() {
  modelManager.createReservation(new Reservation(new Item(1232,"title","author",2002,new MyDate(12,07,2021),"comment") {
    public String toString() {
      return null;
    }
  },"firstname","lastname","test@test.com",true,new MyDate(12,07,2023),new MyDate(24,07,2023)));
  Reservation reservation= modelManager.getReservations().get(0);
  assertEquals(new MyDate(),reservation.getStartDate());
}

报错信息

java.lang.ExceptionInInitializerError
    at javafx.controls/javafx.scene.control.DialogPane.createContentLabel(DialogPane.java:167)
    at javafx.controls/javafx.scene.control.DialogPane.<init>(DialogPane.java:218)
    at javafx.controls/javafx.scene.control.Dialog.<init>(Dialog.java:512)
    at javafx.controls/javafx.scene.control.Alert.<init>(Alert.java:247)
    at javafx.controls/javafx.scene.control.Alert.<init>(Alert.java:222)
    at FairyTaleLib/com.sep1re.fairytalelib.model.LibModelManager.<init>(LibModelManager.java:64)
    at FairyTaleLib/com.sep1re.fairytalelib.model.LibModelManagerTest.setUp(LibModelManagerTest.java:22)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.IllegalStateException: Toolkit not initialized

测试初始化代码

private ArrayList<Item> items;
private LibModelManager modelManager;
@org.junit.jupiter.api.BeforeEach void setUp()
{
  items=new ArrayList();
  modelManager= new LibModelManager();
}

问题根源

LibModelManager构造函数中创建了JavaFX的Alert组件,但JUnit测试环境默认不会初始化JavaFX Toolkit,从而引发Toolkit not initialized异常。

解决方案

方案1:分离UI与业务逻辑(推荐)

  • 将创建Alert的UI代码从业务模型类LibModelManager中抽离,移至专门的UI控制器类。
  • 业务类仅处理核心业务逻辑,通过返回状态标识、触发事件或回调的方式,通知UI层处理弹窗展示。这样测试业务逻辑时完全不依赖JavaFX组件,从根源避免问题。

方案2:在测试中初始化JavaFX Toolkit

若暂时无法重构代码,可在测试类中添加初始化逻辑:

@BeforeAll
static void initJavaFX() {
    // 创建JFXPanel会自动初始化JavaFX Toolkit
    new JFXPanel();
}
  • JFXPanel是JavaFX提供的跨组件嵌入类,实例化它会触发JavaFX Toolkit的初始化,后续创建Alert就不会报错。
  • 需将代码放在@BeforeAll修饰的静态方法中,确保所有测试执行前完成初始化。

方案3:模拟Alert逻辑

如果无需测试Alert的展示效果,可通过Mockito模拟相关依赖:

  • 重构LibModelManager,将创建Alert的逻辑封装为独立服务类,并通过构造函数注入该服务。
  • 测试时用Mockito创建该服务的模拟对象,替换真实的Alert创建逻辑,避免触发JavaFX相关代码。

内容的提问来源于stack exchange,提问作者Babovnik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:39:18