Mock static method with GroovyMock or similar in Spock

匿名 (未验证) 提交于 2019-12-03 01:06:02

问题:

First-timer here, apologies if I've missed anything. I'm hoping to get around a call to a static method using Spock. Feedback would be great

With groovy mocks, I thought I'd be able to get past the static call but haven't found it. For background, I'm in the process of retrofitting tests in legacy java. Refactoring is prohibited. I'm using spock-0.7 with groovy-1.8.

The call to the static method is chained with an instance call in this form:

public class ClassUnderTest{  public void methodUnderTest(Parameter param){   //everything else commented out Thing someThing = ClassWithStatic.staticMethodThatReturnsAnInstance().instanceMethod(param);    }  } 

staticMethod returns an instance of ClassWithStatic instanceMethod returns the Thing needed in the rest of the method

If I directly exercise the global mock, it returns the mocked instance 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     } } 

But if I run the methodUnderTest from the ClassUnderTest:

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     } } 

It throws down a real instance of ClassWithStatic that goes on to fail in its instanceMethod.

回答1:

Spock can only mock static methods implemented in Groovy. For mocking static methods implemented in Java, you'll need to use a tool like GroovyMock , PowerMock or JMockit.

PS: Given that these tools pull of some deep tricks in order to achieve their goals, I'd be interested to hear if and how well they work together with tests implemented in Groovy/Spock (rather than Java/JUnit).



回答2:

Here is how I solved my similar issue (mocking a static method call which is being called from another static class) with Spock (v1.0) and 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"     } } 

The @PowerMockIgnore annotation is optional, only use it if there is some conflicts with existing libraries



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!