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

Kotlin中Mockito3模拟get访问器失效并报空指针问题求助

解决Mockito3启用inline后Mock失效&NPE问题

这种问题我之前也碰到过,结合Mockito 3和mockito-inline的特性,咱们一步步来排查解决:

1. 先确认Mock对象是否真的被初始化了

你遇到的NullPointerException很大概率是因为mock对象本身是null,根本没被正确创建。

  • 如果用了@Mock注解:
    别忘了在测试类上加上@ExtendWith(MockitoExtension::class)(Kotlin)或者@ExtendWith(MockitoExtension.class)(Java),或者在测试方法开头手动调用MockitoAnnotations.openMocks(this)来初始化所有@Mock标记的对象。没做这一步的话,mock就是null,调用mock.myVal自然会触发NPE。

  • 如果是手动创建mock:
    必须用Mockito.mock(YourTargetClass::class.java)(Kotlin)或者Mockito.mock(YourTargetClass.class)(Java)来创建,别用new关键字实例化真实对象,不然那不是Mock。

2. 换用doReturn方式替代when(...).thenReturn

Mockito的when(mock.method()).thenReturn(...)是基于方法调用的语法,但对于final方法(比如Kotlin的val对应的getter默认是final的),有时候会因为字节码处理的顺序问题导致失效,甚至触发NPE。

换成doReturn的语法就更可靠,它是先指定返回值,再绑定到mock对象上,不会触发真实方法的调用:

Kotlin示例:

// 假设你的类是这样的
class MyService {
    val myVal: Boolean get() = true // 真实逻辑返回true
}

// 测试代码
@ExtendWith(MockitoExtension::class)
class MyServiceTest {
    @Mock
    lateinit var mockService: MyService

    @Test
    fun testMockVal() {
        // 用doReturn避免触发真实getter
        doReturn(false).`when`(mockService).myVal
        assert(mockService.myVal == false)
    }
}

Java示例:

public class MyService {
    private boolean myVal = true;
    public boolean isMyVal() { // 真实getter返回true
        return myVal;
    }
}

// 测试代码
@ExtendWith(MockitoExtension.class)
public class MyServiceTest {
    @Mock
    private MyService mockService;

    @Test
    void testMockGetter() {
        doReturn(false).when(mockService).isMyVal();
        assertEquals(false, mockService.isMyVal());
    }
}

3. 别直接访问字段,要通过getter方法

如果你直接写mock.myVal是在访问类的字段而不是调用getter方法,那Mockito根本拦截不到——Mock只能拦截方法调用,直接访问字段是绕过Mock的内存访问,自然会走真实的字段值(可能是null,导致NPE)。

不管是Java还是Kotlin,都要确保你Mock的是getter方法(Kotlin的val本质上是生成了getMyVal()方法,语法糖让你可以直接写myVal,Mockito还是能拦截到的,但前提是mock对象是有效的)。

4. 确认mockito-inline依赖配置正确

要确保你的构建工具里引入的是mockito-inline而不是普通的mockito-core,因为只有mockito-inline支持Mock final类、final方法和Kotlin的val属性:

Gradle配置(Kotlin DSL):

testImplementation("org.mockito:mockito-inline:3.12.4") // 版本和你的Mockito3匹配

Maven配置:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>3.12.4</version>
    <scope>test</scope>
</dependency>

按这几步排查下来,基本就能解决Mock失效和NPE的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:22:47