【发布时间】:2014-12-18 17:43:26
【问题描述】:
我正在尝试使用 Groovy 编写一些 Spock 测试来测试一些 Java 代码(特别是 servlet 过滤器)。我有一些我想模拟的private static 和private static final 变量,但我无法确定是否有办法做到这一点。我知道metaClass 可用于方法,变量有类似的吗?
例如,我有:
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反射来改变值(基于这个问题和答案Change private static final field using Java reflection)。
我想在不添加 Mockito 或其他框架之类的东西的情况下执行此操作,如果可能的话,只需使用普通的 Groovy 和 Spock。
感谢您的任何想法!
更新 1
至少对于 private static 变量,我确实得到了以下工作:
Field field = MyFilter.class.getDeclaredField("CACHE_KEY")
field.setAccessible(true)
field.set(null, "new-key-value")
但我仍然无法绕过final 方面。
更新 2
感谢 Xv。我现在可以使用以下设置:
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")
【问题讨论】:
-
我想这取决于它是如何被测试的,但 IMO 使用旨在做你想做的事情的框架是更好的方法,并且更广泛适用,例如,java.dzone.com/articles/mocking-static-methods-groovy 和 @ 987654323@等
-
感谢您的评论 @DaveNewton - 特别是 Peter Niederwieser 指出在 Spock 中只能模拟 groovy 定义的方法。我的案例特定于类字段/变量,但我将检查其他框架之一是否能够为我执行此操作。谢谢。
-
我知道这不是你要找的东西,但不久前我玩弄了Spock and PowerMock 的组合来模拟静态方法。我不记得它是否也适用于(最终)静态成员,请自己尝试。但我真正想说的是,如果你的代码很难测试,你不应该升级你的测试或测试工具,而是重构代码以提高可测试性。我认为,每当您需要诸如您想要的技巧或工具来提供您想要的东西时,这就是 代码味道。
-
为什么不添加其他框架?有什么特别的原因吗?
-
主要问题是似乎很多框架都可以处理一个困难的测试场景(模拟决赛,模拟构造函数等),过去我尝试添加每个框架来获得我需要一件,那只会弄得一团糟。我希望尽可能地简化依赖关系——这也将有助于减少每个不同框架引入的不同编码范例。
标签: java unit-testing groovy spock