2013-04-05 42 views
12

這裏第一次定時器,如果我錯過了任何事情,請致歉。 我希望能夠繞過使用Spock的靜態方法。反饋會很好使用GroovyMock或Spock中的類似方法模擬靜態方法

隨着groovy嘲笑,我想我能夠通過靜態調用,但還沒有找到它。 對於背景,我正在改造傳統java中的測試過程。重構是被禁止的。我用groovy-1.8使用spock-0.7。

的靜態方法的調用被鏈接在此形式的實例調用:

public class ClassUnderTest{ 

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

} 

STATICMETHOD返回ClassWithStatic instanceMethod的實例返回該方法的其餘部分所需要的東西

如果我直接運行全局模擬,它返回模擬實例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 
    } 
} 

但是如果我運行方法dUnderTest從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 
    } 
} 

它摔倒ClassWithStatic的一個真正的實例繼續在其instanceMethod失敗。

+1

如果幫助某人,我在Spock中使用GroovyMock來更改Java代碼中的靜態方法,但是這會錯誤地影響其他測試。我用這個註釋來解決問題@ConfineMetaClassChanges – Topera 2016-10-14 00:49:25

回答

15

Spock只能模擬在Groovy中實現的靜態方法。爲了模擬用Java實現的靜態方法,您需要使用一個工具,如GroovyMock,PowerMockJMockit。 PS:考慮到這些工具爲了實現他們的目標而引入了一些深入的技巧,我有興趣瞭解他們是否能夠以及如何與在Groovy/Spock(而不是Java/JUnit)中實現的測試一起工作, 。

+0

謝謝彼得。將有一個集成,讓你知道 – alexgibbs 2013-04-05 23:09:58

+0

你有答案嗎?我在這裏看到一個例子: https://github.com/kriegaex/Spock_PowerMock – JavaJigs 2016-07-18 13:46:54

2

這是我如何解決我類似的問題(嘲諷它正在從另一個靜態類稱爲靜態方法調用)與斯波克(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註釋是可選的,只有在與現有庫存在衝突時才使用它。

相關問題