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
相关产品推荐
相关产品推荐

