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

JUnit测试中如何复用对象?使用@BeforeAll初始化静态对象报空指针如何解决

问题原因

空指针异常的核心原因是@BeforeAll注解的初始化方法未满足JUnit的执行规则,导致方法根本没有触发运行,d1、d2、d3三个静态变量始终为null,调用equals方法时就会抛出空指针。

解决方案

根据你使用的JUnit版本选择对应修改方式即可实现对象复用:

方案1:JUnit 5 默认规则适配(推荐)

JUnit 5 中@BeforeAll默认要求修饰的方法必须是静态,只需要给你的setup方法增加static修饰符即可,修改后代码如下:

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class MyTests {
   
    static Date d1, d2, d3;

    @BeforeAll
    public static void setup() {
        d1 = new Date(7, 11, 2021);
        d2 = new Date(7, 11, 2021);
        d3 = new Date(1, 11, 1990);
    }

    @Test
    public void testDateEquals() {
        assertTrue(d1.equals(d2));
        assertFalse(d2.equals(d3));
    }
}

方案2:JUnit 5 单实例生命周期适配

如果不想使用静态方法,可以给测试类添加@TestInstance(TestInstance.Lifecycle.PER_CLASS)注解,此时JUnit会为所有测试方法共用同一个测试类实例,@BeforeAll可以修饰非静态方法,变量也可以不用static修饰:

import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class MyTests {
   
    Date d1, d2, d3;

    @BeforeAll
    public void setup() {
        d1 = new Date(7, 11, 2021);
        d2 = new Date(7, 11, 2021);
        d3 = new Date(1, 11, 1990);
    }

    @Test
    public void testDateEquals() {
        assertTrue(d1.equals(d2));
        assertFalse(d2.equals(d3));
    }
}

方案3:JUnit 4 适配

如果你使用的是JUnit 4,没有@BeforeAll注解,对应的全局初始化注解为@BeforeClass,同样要求修饰静态方法,修改后代码如下:

import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

public class MyTests {
   
    static Date d1, d2, d3;

    @BeforeClass
    public static void setup() {
        d1 = new Date(7, 11, 2021);
        d2 = new Date(7, 11, 2021);
        d3 = new Date(1, 11, 1990);
    }

    @Test
    public void testDateEquals() {
        assertTrue(d1.equals(d2));
        assertFalse(d2.equals(d3));
    }
}

注意:如果你的Date类是可变对象,在测试中会修改对象属性,建议使用@BeforeEach注解替换@BeforeAll,每个测试方法运行前都会重新初始化对象,避免不同测试之间互相干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:24:08