2011-12-01 30 views
6

我在測試設置如下:如何重置Groovy中的模擬靜態方法?

def originalPostAsXml = RestClient.&postAsXml 

    RestClient.metaClass.'static'.postAsXml = { 
     String uriPath, String xml -> 
     return 65536 
    } 

,並在測試清理:

RestClient.metaClass.'static'.postAsXml = originalPostAsXml 

下一次測試運行,當它試圖執行RestClient.postAsXml,它運行到但StackOverflowError:

at groovy.lang.Closure.call(Closure.java:282) 

它看起來像RestClient.postAsXml遞歸地指向自己。什麼是重置模擬靜態方法的正確方法?上述

+0

這裏有一個以前類似的問題:http://stackoverflow.com/questions/920582/how-to-change-behaviour-of-the-methed-in-groovy-using -that-method-in-metaclass – schmolly159

+0

你可以重置元類 - 看到這個問題有答案http://stackoverflow.com/questions/1612569/how-do-i-undo-meta-class-changes-after-executing -groovyshell –

回答

1

schmolly159的提示使我以下解決方案:

def originalPostAsXml = RestClient.metaClass.getMetaMethod('postAsXml', [String, String] as Class[]) 

然後復位方法:

RestClient.metaClass.'static'.postAsXml = { String uriPath, String xml -> 
     originalPostAsXml.invoke(delegate, uriPath, xml) 
    } 
6

在一個單元測試,所以經常元類設置爲nulltearDown()其中似乎可以讓班級在沒有我的修改的情況下像原來一樣工作。

例如:

void setUp() { 
    super.setUp() 
    ServerInstanceSettings.metaClass.'static'.list = { 
     def settings = [someSetting:'myOverride'] as ServerInstanceSettings 
     return [settings] 
    } 
} 

void tearDown() { 
    super.tearDown() 
    ServerInstanceSettings.metaClass.'static'.list = null 
} 

如果您正在使用JUnit4可以使用@AfterClass相反在這種情況下,這使得更多的意義或許。

2

我發現簡單設置<Class>.metaClass = null適合我。

斯波克例子:

def "mockStatic Test"(){ 
    given: 
    RestClient.metaClass.static.postAsXml = { 
    String uriPath, String xml -> 
    return 65536 
    } 

    when: 
    //some call that depends on RestClient.postAsXml 

    then: 
    //Expected outcomes 

    cleanup: 
    //reset metaclass 
    RestClient.metaClass = null 
} 
相關問題