第一次来这里,如果我错过了什么,请道歉。我希望使用Spock来绕过对静态方法的调用。反馈会很好
使用groovy mock,我以为我可以跳过静态调用,但是还没有找到它。作为背景,我正在改造遗留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
如果我直接执行全局mock,它会返回mock示例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运行方法UnderTest:
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中继续失败。
5条答案
按热度按时间yv5phkfx1#
Spock只能模拟Groovy中实现的静态方法。要模拟Java中实现的静态方法,您需要使用GroovyMock、PowerMock或JMockit等工具。
PS:考虑到这些工具为了实现它们的目标而使用了一些深层次的技巧,我很想知道它们是否能与在Groovy/Spock(而不是Java/JUnit)中实现的测试一起工作,以及工作得如何。
hs1ihplo2#
下面是我如何用Spock(v1.0)和PowerMock(v1.6.4)解决类似问题(模拟从另一个静态类调用的静态方法调用)的方法。
@PowerMockIgnore
注解是可选的,仅当与现有库存在冲突时才使用rxztt3cl3#
在Groovy/Spock中,我绕过静态方法的方法是创建代理类,并在实际代码中将其替换掉。这些代理类只返回您需要的静态方法。您只需将代理类传递给您正在测试的类的构造函数。
因此,当您编写测试时,您将接触到代理类(然后它将返回静态方法),并且您应该能够以这种方式进行测试。
zy1mlcev4#
一种解决方法是将静态方法调用 Package 到示例方法中。
现在,您可以使用Spy模拟静态方法。
如果 Package 器方法应该返回一个值,你也可以在固定的响应中为 Package 器方法设置存根。这个解决方案只使用Spock内置函数,并且可以与Java和Groovy类一起工作,而不依赖于PowerMock或GroovyMock。
hmmo2u0o5#
我最近发现了'
spock.mockfree
'包,它帮助模拟final类和静态类/方法。它和这个框架一样非常简单,在这个例子中,你只需要Spy()测试下的类和@MockStatic你需要的静态方法。示例:
我们使用了StaticMethodClass类的静态方法returnA
这是调用代码
现在我们需要测试CallStaticMethodClass类的useStatic方法但是spock本身并不支持mock静态方法,而我们支持
我们使用@MockStatic注解来标记哪个类需要被mock直接在其下实现需要mock的静态方法,方法签名保持不变,但实现不同。
链接到框架:https://github.com/sayweee/spock-mockfree/blob/498e09dc95f841c4061fa8224fcaccfc53904c67/README.md