使用Spock在Java中模拟私有静态最终变量 [英] Using Spock to mock private static final variables in Java
问题描述
我试图用Groovy编写一些Spock测试来测试一些Java代码(特别是Servlet过滤器).我有一些要模拟的private static
和private static final
变量,但是我无法确定是否有办法做到这一点.我知道metaClass
可用于方法,变量是否有类似的东西?
I'm trying to write some Spock tests with Groovy to test some Java code (specifically a servlet Filter). I have some private static
and private static final
variables that I would like to mock, but I can't determine if there is a way to do this. I know metaClass
is available for methods, is there anything similar for variables?
例如,我有:
public class MyFilter implements Filter {
private static WebResource RESOURCE;
private static final String CACHE_KEY = "key-to-be-used-for-cache";
... actual methods, etc ...
}
我尝试使用Mock(MyFilter)
,以及使用Java反射来更改值(基于此问题并回答
I've tried using Mock(MyFilter)
, as well as using Java reflection to change the value (based on this question and answer Change private static final field using Java reflection).
我想在不添加Mockito或其他框架的情况下执行此操作,如果可能的话,只需使用普通的Groovy和Spock.
I would like to do this without adding something like Mockito or other frameworks, if that's possible, just use plain Groovy and Spock.
感谢任何想法!
更新1
至少对于private static
变量,我确实可以完成以下工作:
At least for private static
variables I did get the following to work:
Field field = MyFilter.class.getDeclaredField("CACHE_KEY")
field.setAccessible(true)
field.set(null, "new-key-value")
但是我仍然无法绕过final
方面.
But I still haven't been able to get around the final
aspect.
更新2
感谢Xv.我现在可以使用以下设置:
Thanks to Xv. I can now set this with the following:
Field field = MyFilter.class.getDeclaredField("CACHE_KEY")
field.setAccessible(true)
Field modifiersField = Field.class.getDeclaredField("modifiers")
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, "new-key-value")
推荐答案
基于我从 https://stackoverflow.com中学到的知识/a/25031713/239408 ,这在spock中对我有用
Based on what I learned from https://stackoverflow.com/a/25031713/239408, this works for me in spock
import java.lang.reflect.Field
import java.lang.reflect.Modifier
...
def setup() {
Field field = BackendCredentials.getDeclaredField("logger")
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, Mock(Logger))
}
好像您缺少Modifier.FINAL
标志的取消设置.
Looks like you are missing the unsetting of the Modifier.FINAL
flag.
这篇关于使用Spock在Java中模拟私有静态最终变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!