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

类成员变量调用ApplicationContext.getBean加载Bean时如何编写Junit测试

问题根因

类级别的成员变量会在类加载阶段完成初始化,你写的Beanx beanx = ApplicationContext.getBean("beanName")会在类加载时直接触发Spring容器的Bean查询,而Junit测试默认会先加载业务类,再初始化Spring上下文,此时ApplicationContext实例还未赋值,自然触发空指针异常。

可行解决方案

方案1:调整Bean注入方式,避免硬编码获取Bean

这是最优解,从根源上避免硬编码依赖容器的问题:

  • 改用Spring原生依赖注入替代ApplicationContext.getBean()硬编码调用,把Beanx声明为类的普通成员变量,加@Autowired/@Resource注解注入即可
  • 业务代码优化示例:
// 原错误写法
// public class YourService {
//    private Beanx beanx = ApplicationContext.getBean("beanName");
// }

// 优化后写法
@Component
public class YourService {
    @Autowired
    private Beanx beanx;
}
  • 测试类直接用Spring测试注解即可自动完成依赖注入:
@SpringBootTest
public class YourServiceTest {
    @Autowired
    private YourService yourService;

    @Test
    public void testBizLogic() {
        // 编写测试逻辑即可
    }
}

方案2:无法修改业务代码时,Mock静态方法返回

如果原有业务逻辑不允许调整,用Mock工具模拟ApplicationContext.getBean()的返回,跳过真实调用:

  • 引入Mockito 4.0+版本(支持静态方法Mock),测试类写法如下:
@ExtendWith(MockitoExtension.class)
public class YourServiceTest {
    @Mock
    private Beanx mockBeanx;

    // 如果是静态类变量,需要把Mock逻辑放在@BeforeAll中,保证Mock在业务类加载前执行
    @BeforeEach
    public void initMock() {
        MockedStatic<ApplicationContext> mockedContext = Mockito.mockStatic(ApplicationContext.class);
        mockedContext.when(() -> ApplicationContext.getBean("beanName")).thenReturn(mockBeanx);
        // 上下文Mock完成后再实例化业务类
        YourService yourService = new YourService();
    }

    @Test
    public void testBizLogic() {
        // 提前Mock Beanx对应方法的返回值
        when(mockBeanx.bizMethod(any())).thenReturn("模拟返回结果");
        // 执行测试逻辑
    }
}

方案3:需要用真实Bean测试时,调整加载顺序

如果测试需要依赖真实的Beanx实例,调整测试类的初始化顺序,先完成Spring上下文加载再实例化业务类:

@SpringBootTest
public class YourServiceTest {
    private YourService yourService;

    // 注入已经初始化完成的Spring上下文
    @BeforeEach
    public void init(ApplicationContext context) {
        // 上下文准备完成后再实例化业务类,此时getBean可以正常拿到实例
        yourService = new YourService();
    }

    @Test
    public void testBizLogic() {
        // 编写测试逻辑即可
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 10:06:04