如何为Java中的Singleton类编写单元测试并解决空指针异常问题
问题根因
你对Singletone类执行全量静态mock后,所有静态方法默认返回null,你没有预先给getInstance(1)定义返回值,直接链式调用.getDAO()就会触发空指针。同时你给出的测试代码存在两处语法错误:
- 类字面量写法错误,
AddUserDAO.Class应改为AddUserDAO.class - 需确认单例类名是否拼写正确,你代码中写的是
Singletone,常规写法为Singleton,拼写错误也会引发异常
解决方案
方案1:全量静态mock后依次打桩
先给getInstance方法打桩返回mock的单例实例,再对实例的getDAO方法打桩,示例代码如下:
@RunWith(PowerMockRunner.class) @PrepareForTest({Singletone.class}) public class SingletoneTest { @Test public void test() { // 构造mock的单例实例 Singletone mockSingleton = mock(Singletone.class); PowerMockito.mockStatic(Singletone.class); // 给静态getInstance方法打桩 when(Singletone.getInstance(1)).thenReturn(mockSingleton); AddUserDAO addUser = mock(AddUserDAO.class); // 给实例的getDAO方法打桩 when(mockSingleton.getDAO()).thenReturn(addUser); // 此处补后续测试逻辑 } }
方案2:用spy保留单例真实逻辑
如果你需要保留getInstance的真实初始化逻辑,只针对getDAO方法打桩,可以用静态spy替代全量mock,示例代码如下:
@RunWith(PowerMockRunner.class) @PrepareForTest({Singletone.class}) public class SingletoneTest { @Before public void setup() { // spy仅对显式打桩的方法做mock,其余方法走真实业务逻辑 PowerMockito.spy(Singletone.class); } @Test public void test() { AddUserDAO addUser = mock(AddUserDAO.class); when(Singletone.getInstance(1).getDAO()).thenReturn(addUser); // 此处补后续测试逻辑 } }
内容的提问来源于stack exchange,提问作者Sumit Sharma
相关产品推荐
相关产品推荐

