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

查看:32
本文介绍了使用 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 反射来更改值(基于此问题和答案 使用 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天全站免登陆