这里的第一个计时器,如果我错过任何事情,我会道歉。 我希望能够使用Spock来调用静态方法。反馈会很棒
使用groovy模拟器,我以为我能够通过静态调用但没有找到它。 作为背景,我正在改进遗留Java中的测试。禁止重构。我正在使用spock-0.7和groovy-1.8。
对静态方法的调用以这种形式的实例调用进行链接:
public class ClassUnderTest{
public void methodUnderTest(Parameter param){
//everything else commented out
Thing someThing = ClassWithStatic.staticMethodThatReturnsAnInstance().instanceMethod(param);
}
}
staticMethod返回ClassWithStatic的一个实例 instanceMethod返回方法其余部分所需的Thing
如果我直接运用全局模拟,它会返回模拟的实例ok:
def exerciseTheStaticMock(){
given:
def globalMock = GroovyMock(ClassWithStatic,global: true)
def instanceMock = Mock(ClassWithStatic)
when:
println(ClassWithStatic.staticMethodThatReturnsAnInstance().instanceMethod(testParam))
then:
interaction{
1 * ClassWithStatic.staticMethodThatReturnsAnInstance() >> instanceMock
1 * instanceMock.instanceMethod(_) >> returnThing
}
}
但是如果我从ClassUnderTest运行methodUnderTest:
def failingAttemptToGetPastStatic(){
given:
def globalMock = GroovyMock(ClassWithStatic,global: true)
def instanceMock = Mock(ClassWithStatic)
ClassUnderTest myClassUnderTest = new ClassUnderTest()
when:
myClassUnderTest.methodUnderTest(testParam)
then:
interaction{
1 * ClassWithStatic.staticMethodThatReturnsAnInstance() >> instanceMock
1 * instanceMock.instanceMethod(_) >> returnThing
}
}
它抛出了一个真实的ClassWithStatic实例,它在instanceMethod中失败了。
答案 0 :(得分:19)
Spock只能模拟在Groovy中实现的静态方法。对于使用Java实现的静态方法的模拟,您需要使用GroovyMock,PowerMock或JMockit等工具。
PS:鉴于这些工具为了实现目标而采取了一些深层技巧,我很想知道它们是否以及如何与Groovy / Spock(而不是Java / JUnit)中实现的测试一起工作。答案 1 :(得分:2)
以下是我如何使用Spock(v1.0)和PowerMock(v1.6.4)解决我的类似问题(模拟从另一个静态类调用的静态方法调用)
import org.junit.Rule
import org.powermock.core.classloader.annotations.PowerMockIgnore
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.rule.PowerMockRule
import spock.lang.Specification
import static org.powermock.api.mockito.PowerMockito.mockStatic
import static org.powermock.api.mockito.PowerMockito.when
@PrepareForTest([YourStaticClass.class])
@PowerMockIgnore(["javax.xml.*", "ch.qos.logback.*", "org.slf4j.*"])
class YourSpockSpec extends Specification {
@Rule
Powermocked powermocked = new Powermocked();
def "something something something something"() {
mockStatic(YourStaticClass.class)
when: 'something something'
def mocked = Mock(YourClass)
mocked.someMethod(_) >> "return me"
when(YourStaticClass.someStaticMethod(xyz)).thenReturn(mocked)
then: 'expect something'
YourStaticClass.someStaticMethod(xyz).someMethod(abc) == "return me"
}
}
@PowerMockIgnore
注释是可选的,只有在与现有库存在冲突时才使用它
答案 2 :(得分:0)
我在Groovy / Spock中解决静态方法的方法是通过创建在实际代码中替换掉的代理类。这些代理类仅返回所需的静态方法。您只需将代理类传递给要测试的类的构造函数即可。
因此,在编写测试时,您将接触到代理类(该类将返回静态方法),并且应该能够以这种方式进行测试。