使用Spock在Java中模拟私有静态最终变量 [英] Using Spock to mock private static final variables in Java

查看:269
本文介绍了使用Spock在Java中模拟私有静态最终变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用Groovy编写一些Spock测试来测试一些Java代码(特别是Servlet过滤器).我有一些要模拟的private staticprivate 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆