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

Mockito问题:为Spy对象设置值后调用get方法返回null

问题原因及解决办法

你遇到的问题核心是:ContainerRequestContext是接口,Mockito对接口创建的Spy对象,默认只会记录方法的调用行为,不会自动为接口方法添加状态存储逻辑。

哪怕你通过someMethodThatSetsTheSecurityContext调用了setSecurityContext,这个Spy对象本身没有对应的字段来保存传入的SecurityContext实例,所以调用getSecurityContext()时自然返回null——而verify()能通过,只是因为Mockito记录了setSecurityContext方法确实被调用过,和对象内部状态无关。

两种解决思路

1. 手动存根set/get方法,维护状态

自己给Spy的setSecurityContext和getSecurityContext方法添加逻辑,用一个变量保存传入的SecurityContext:

SecurityContext storedSecurityContext = null;
ContainerRequestContext requestContext = spy(ContainerRequestContext.class);

// 存根set方法,把传入的SecurityContext存到变量里
doAnswer(invocation -> {
    storedSecurityContext = invocation.getArgument(0);
    return null;
}).when(requestContext).setSecurityContext(any(SecurityContext.class));

// 存根get方法,返回保存的变量
when(requestContext.getSecurityContext()).thenReturn(storedSecurityContext);

someMethodThatSetsTheSecurityContext(requestContext);

verify(requestContext).setSecurityContext(argument.capture());
assertEquals("myUserName", argument.getValue().getUserPrincipal().getName());
assertNotNull(requestContext.getSecurityContext());

2. 使用真实的实现类创建Spy

如果你的项目里有ContainerRequestContext的具体实现类(比如Jersey的ContainerRequest、RESTEasy的对应实现),直接Spy这个真实类而非接口。真实类本身会有字段保存SecurityContext,调用set后get自然能返回正确值:

// 假设用Jersey的ContainerRequest作为实现类
ContainerRequest requestContext = spy(new ContainerRequest(null, null, null));

someMethodThatSetsTheSecurityContext(requestContext);

verify(requestContext).setSecurityContext(argument.capture());
assertEquals("myUserName", argument.getValue().getUserPrincipal().getName());
assertNotNull(requestContext.getSecurityContext());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:45:36