2011-12-01 69 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 
} 
相关问题