单元测试中@Inject注入的Optional对象为何为null?
问题原因与解决方案
问题根源
- 测试类中的
testPerson是独立变量,和testRoom实例内的person1字段没有任何绑定关系,你对testPerson的赋值不会同步到Room对象里。 - Mockito的
@InjectMocks默认不支持自动注入Optional类型的依赖,它无法自动将Person实例包装成Optional注入到Room中。
解决方案
方案1:通过反射直接设置Room私有字段
这是最直接的临时解决方式:
@Test public void testSuccess() { Optional<Person> testPerson = Optional.of(new Person()); // 反射访问并修改Room的person1字段 try { Field personField = Room.class.getDeclaredField("person1"); personField.setAccessible(true); personField.set(testRoom, testPerson); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } // 执行你的测试逻辑 }
方案2:改用构造注入(推荐)
修改Room类使用构造注入,测试时可以直接手动传入依赖,彻底避免DI框架的适配问题:
// 修改后的Room类 public class Room { private final Optional<Person> person1; @Inject public Room(Optional<Person> person1) { this.person1 = person1; } // 原业务方法 }
对应的测试类可以简化为:
public class RoomTest { private Room testRoom; @Test public void testSuccess() { Optional<Person> testPerson = Optional.of(new Person()); // 直接构造Room实例,传入需要的依赖 testRoom = new Room(testPerson); // 执行测试逻辑 } }
方案3:结合Mockito Mock与手动注入
如果需要Mock Person对象而非使用真实实例,可以先Mock Person,再手动包装成Optional注入:
public class RoomTest { @InjectMocks private Room testRoom; @Mock private Person mockPerson; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); // 将Mock的Person包装成Optional注入到Room try { Field personField = Room.class.getDeclaredField("person1"); personField.setAccessible(true); personField.set(testRoom, Optional.of(mockPerson)); } catch (Exception e) { e.printStackTrace(); } } @Test public void testSuccess() { // 测试逻辑,可正常使用mockPerson } }
内容的提问来源于stack exchange,提问作者Aditya Mahajan
相关产品推荐
相关产品推荐

