Mockito测试报错:非空参数为null,如何注入ArchiveService字段?
相关代码
ArchiveService 实现
@Service class ArchiveService( val fnaReactiveClient: FNAReactiveClient, val resolvedTopicPrefix: String)
CoreKafkaConfig 配置类
@Configuration @EnableAspectJAutoProxy(proxyTargetClass = true) class CoreKafkaConfig { @Value("\${kafka.topicPrefix:}") lateinit var topicPrefix: String @Bean fun resolvedTopicPrefix() = run { KafkaTopicsUtil.resolveTopicPrefix(topicPrefix) } }
测试类 ArchiveServiceTest
@ExtendWith(MockitoExtension::class) class ArchiveServiceTest { @InjectMocks lateinit var archiveService: ArchiveService @Mock lateinit var fnaReactiveClient: FNAReactiveClient @Test fun `create archive with duplicate filenames`() { val user = "user" // ... some when and given block .... val newDocVer = archiveService.archiveDoc("integration", null, req, ecmHeaders, EcmServiceAsyncConfig.MethodType.ARCHIVE) assertEquals(newId, newDocVer) // ... some verify block .... } }
抛出异常
Cannot instantiate @InjectMocks field named 'archiveService' of type 'class tu.xxxx.ecm.services.service.ArchiveService'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : Parameter specified as non-null is null: method tu.xxx.ecm.services.service.ArchiveService., parameter resolvedTopicPrefix
请问哪里操作错误了?
问题出在测试类中:你仅为ArchiveService的第一个构造参数fnaReactiveClient添加了@Mock注解,但第二个非空参数resolvedTopicPrefix(字符串类型)没有提供任何实例。Mockito自动构造ArchiveService时,无法生成该字符串参数的实例,导致因为非空参数为null而抛出异常。
有两种解决方式:
方法一:手动提供字符串参数
在测试类中添加resolvedTopicPrefix的实例,Mockito会自动将其注入到构造参数中:@ExtendWith(MockitoExtension::class) class ArchiveServiceTest { @InjectMocks lateinit var archiveService: ArchiveService @Mock lateinit var fnaReactiveClient: FNAReactiveClient // 添加该字段,值可根据测试场景自定义 private val resolvedTopicPrefix = "test-topic-prefix" }方法二:加载Spring测试上下文
如果需要贴近真实运行环境,可改用@SpringBootTest启动Spring上下文,配合@MockBean替换fnaReactiveClient,Spring会自动注入resolvedTopicPrefix这个Bean:@SpringBootTest class ArchiveServiceTest { @Autowired lateinit var archiveService: ArchiveService @MockBean lateinit var fnaReactiveClient: FNAReactiveClient // 测试方法逻辑保持不变 }
注意:第一种方法启动速度快,适合单元测试;第二种方法更贴近真实环境,但测试启动耗时更长。
内容的提问来源于stack exchange,提问作者Anton Rodriges

