SpringBoot中Mockito单元测试NPE求助:IdGenerator注入异常
问题分析与解决
核心原因
测试类未正确给MessageEventGenerator注入IdGeneratorConfig实例,导致调用idGenerator.newIdGenerator()触发空指针异常;同时代码存在变量名错误、笔误、逻辑遗漏等问题。
具体修复步骤
1. 修正测试类的配置与变量问题
public class MessageTest { // 直接创建IdGeneratorConfig实例 private IdGeneratorConfig idGeneratorConfig = new IdGeneratorConfig(); @Mock private IKafkaService kafkaService; // 修正被测对象类型与变量名 @ExtendWith(MockitoExtension.class) @InjectMocks private MessageEventGenerator messageEventGenerator; @Before public void setUp() { MockitoAnnotations.openMocks(this); // 手动给被测对象注入IdGeneratorConfig messageEventGenerator.setIdGenerator(idGeneratorConfig); } @Test public void testGenerateAndSendEventIngestion() { Message message = new Message(); message.setMsgId(12356486); message.setCustomId("custom1"); message.setRecipientEmail("exemple@example.com"); message.setMetadata("metadatamail"); long expectedEventId = idGeneratorConfig.idGenerator().ranId(); System.out.println(expectedEventId); MessageEvent messageEvent = (MessageEvent) messageEventGenerator.generateEvent(message); messageEvent.setEventId(expectedEventId); assert messageEvent != null; // 修正断言值,与message设置的MsgId保持一致 assertEquals(12356486, messageEvent.getMsgId()); assertEquals("custom1", messageEvent.getCustomId()); assertEquals("exemple@example.com", messageEvent.getRecipient()); assertEquals("metadatamail", messageEvent.getMetadata()); messageEventGenerator.sendEvent(messageEvent); // 修正sendEvent的第二个参数,与待测试类逻辑一致 verify(kafkaService, times(1)).sendEvent(messageEvent, "newEvent"); } }
- 删除重复定义的
@Mock private IKafkaService kafkaService; - 修正被测对象类型:从
IngestedEventGenerator改为MessageEventGenerator,统一变量名 - 手动注入
IdGeneratorConfig实例(Mockito的@InjectMocks无法自动注入非Mock类)
2. 修正待测试类的笔误与逻辑问题
public class MessageEventGenerator implements IEventGenerator { @Autowired private IdGeneratorConfig idGeneratorConfig; @Autowired private IKafkaService kafkaService; // 添加setter方法,方便测试注入 public void setIdGenerator(IdGeneratorConfig idGeneratorConfig) { this.idGeneratorConfig = idGeneratorConfig; } @Override public void sendEvent(Event event) { kafkaService.sendEvent(event,"newEvent"); } @Override public Event generateEvent(Message message) { // 修正方法调用:IdGeneratorConfig的方法是idGenerator(),不是newIdGenerator() long eventId = idGeneratorConfig.idGenerator().ranId(); MessageEvent messageEvent = new MessageEvent(); messageEvent.setMsgId(message.getMsgId()); messageEvent.setCustomId(message.getCustomId()); // 修正变量引用:用定义好的eventId替代未声明的SnowId messageEvent.setEventId(eventId); messageEvent.setMetadata(message.getMetadata()); // 补充设置recipient字段,否则断言会失败 messageEvent.setRecipient(message.getRecipientEmail()); return messageEvent; } } @Configuration public class IdGeneratorConfig { @Bean @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) public IdGenerator idGenerator() { return new IdGenerator(); } }
- 修正
IdGeneratorConfig的调用方法名 - 修正
setEventId的变量引用 - 补充
recipient字段的赋值逻辑 - 添加
setIdGenerator方法,方便测试注入
3. 可选:使用Spring测试上下文简化注入
如果项目基于Spring Boot,可改用@SpringBootTest和@MockBean自动管理Bean,避免手动注入:
@SpringBootTest public class MessageTest { @Autowired private MessageEventGenerator messageEventGenerator; @MockBean private IKafkaService kafkaService; @Test public void testGenerateAndSendEventIngestion() { // 测试逻辑同上 } }
此方式下Spring会自动注入IdGeneratorConfig和MessageEventGenerator,同时用Mock替换IKafkaService。
内容的提问来源于stack exchange,提问作者Mohamed amine ben hassen
相关产品推荐
相关产品推荐

