我有一个带有一些静态方法的类.我需要模拟这些静态方法.我知道PowerMock会这样做,但是我无法找到任何能够解释"Spock + PowerMock"集成的教程/材料.我更喜欢Spock和Junit,因此是一个难题.有没有办法让这两个框架发挥作用?任何帮助都非常感激.示例代码,更是如此.
更新:方法的当前状态
我正在尝试用Groovy编写一些Spock测试来测试一些Java代码(特别是一个servlet Filter).我有一些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 ...
}
Run Code Online (Sandbox Code Playgroud)
我尝试过使用Mock(MyFilter),以及使用Java反射来更改值(基于此问题并使用Java反射更改私有静态最终字段).
我想这样做而不添加像Mockito或其他框架的东西,如果可能的话,只需使用普通的Groovy和Spock.
谢谢你的任何想法!
更新1
至少对于private static变量,我确实得到以下工作:
Field field = MyFilter.class.getDeclaredField("CACHE_KEY")
field.setAccessible(true)
field.set(null, "new-key-value")
Run Code Online (Sandbox Code Playgroud)
但我仍然无法绕过这个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")
Run Code Online (Sandbox Code Playgroud) 我正在尝试readAttributes使用 groovy 的metaClass约定来模拟静态方法之一,但实际方法被调用。
这就是我嘲笑静态函数的方式:
def "test"() {
File file = fold.newFile('file.txt')
Files.metaClass.static.readAttributes = { path, cls ->
null
}
when:
fileUtil.fileCreationTime(file)
then:
1 * fileUtil.LOG.debug('null attribute')
}
Run Code Online (Sandbox Code Playgroud)
我在这里做错了吗?
我的java方法
public Object fileCreationTime(File file) {
try {
BasicFileAttributes attributes = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
if(attributes == null) {
LOG.debug("null attribute");
}
//doSomething
} catch (IOException exception) {
//doSomething
}
return new Object();
}
Run Code Online (Sandbox Code Playgroud) 我已经在 StackOverflow 和 Google 上搜索了一段时间,试图找到能够在 Spock 规范中运行此代码的正确配置/语法:
Sql mockSql = Mock()
Run Code Online (Sandbox Code Playgroud)
但是,当我运行单元测试时,CGLIB 向我抛出了一个令人讨厌的异常:
java.lang.IllegalAccessError: tried to access method groovy.sql.Sql.<init>()V from class groovy.sql.Sql$$EnhancerByCGLIB$$d0b7cd7f
at org.spockframework.mock.runtime.MockInstantiator.instantiate(MockInstantiator.java:33)
at org.spockframework.mock.runtime.ProxyBasedMockFactory$CglibMockFactory.createMock(ProxyBasedMockFactory.java:92)
at org.spockframework.mock.runtime.ProxyBasedMockFactory.create(ProxyBasedMockFactory.java:49)
at org.spockframework.mock.runtime.JavaMockFactory.create(JavaMockFactory.java:51)
at org.spockframework.mock.runtime.CompositeMockFactory.create(CompositeMockFactory.java:44)
at org.spockframework.lang.SpecInternals.createMock(SpecInternals.java:47)
at org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:282)
at org.spockframework.lang.SpecInternals.MockImpl(SpecInternals.java:83)
Run Code Online (Sandbox Code Playgroud)
我看了这个问题/答案 -用 GroovyMock 或 Spock 中的类似方法模拟静态方法- 希望它可以给我一个很好的起点,但在我的例子中被嘲笑的类,groovy.Sql 是一个 groovy 类,所以我不是确定这是正确的起点。
我已经使用 GroovyMock 在其他单元测试中成功地测试了 Groovy.Sql,但我希望我可能只是错过了一些可以使它成功的东西,这样我就可以让 Spock 魔术和 Groovy SQL 一起快乐起来。如果我只是在某处错过了答案,我深表歉意 - 希望我不会重复其他人的询问。