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

Mockito @InjectMocks注入失效,手动构造正常的问题求助

问题原因及解决方案

常见原因

  1. 缺失passwordEncoder的@Mock声明
    你提到已用@Mock声明了tokenService、jwtDecoder,但可能遗漏了passwordEncoder的@Mock注解。@InjectMocks只会注入已被@Mock(或@Spy)标记的实例,未声明的依赖会被留空,调用其方法自然抛出空指针。

  2. Kotlin类的构造函数/属性可见性限制

    • 如果MailLoginService的passwordEncoder是private val字段而非构造函数参数,Mockito的反射机制在Kotlin默认的访问控制下无法注入私有字段。
    • 若MailLoginService存在多个构造函数,@InjectMocks可能选择了不包含passwordEncoder的构造函数,导致依赖未注入。
  3. Mockito注解未正确初始化
    若测试类未通过@ExtendWith(MockitoExtension::class)或MockitoAnnotations.openMocks(this)启动Mockito注解处理,@InjectMocks和@Mock都不会生效,但你手动构造能运行,这个可能性较低。

解决方案

方案1:补全passwordEncoder的@Mock声明

确保所有需要注入的依赖都用@Mock标记,示例代码:

import org.junit.jupiter.api.Test
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.junit.jupiter.api.extension.ExtendWith

@ExtendWith(MockitoExtension::class)
class MailLoginServiceTest {
    @Mock
    lateinit var tokenService: TokenService

    @Mock
    lateinit var jwtDecoder: JwtDecoder

    @Mock // 必须添加这个注解
    lateinit var passwordEncoder: PasswordEncoder

    @InjectMocks
    lateinit var mailLoginService: MailLoginService

    @Test
    fun testPasswordEncoding() {
        // 测试逻辑,此时passwordEncoder已被注入mock实例
    }
}

方案2:使用构造函数注入(推荐)

让MailLoginService通过主构造函数接收所有依赖,@InjectMocks会优先使用构造函数注入,避免字段访问权限问题:

// 业务类
class MailLoginService(
    private val tokenService: TokenService,
    private val jwtDecoder: JwtDecoder,
    private val passwordEncoder: PasswordEncoder
) {
    fun encodePassword(rawPassword: String): String {
        return passwordEncoder.encode(rawPassword)
    }
}

这种方式无需修改属性可见性,且符合依赖注入的最佳实践,Mockito能可靠地注入所有@Mock实例。

方案3:调整字段可见性(仅当无法使用构造函数注入时)

如果必须用字段注入,可将passwordEncoder标记为internal或添加@JvmField注解,让Mockito能反射访问:

class MailLoginService {
    @JvmField // 允许Mockito通过反射注入
    lateinit var passwordEncoder: PasswordEncoder

    @JvmField
    lateinit var tokenService: TokenService

    @JvmField
    lateinit var jwtDecoder: JwtDecoder
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 15:52:27