如何在Groovy中重置模拟静态方法?

Noe*_*Yap 8 groovy

我在测试设置中有以下内容:

    def originalPostAsXml = RestClient.&postAsXml

    RestClient.metaClass.'static'.postAsXml = {
        String uriPath, String xml ->
        return 65536
    }
Run Code Online (Sandbox Code Playgroud)

并在测试清理中:

    RestClient.metaClass.'static'.postAsXml = originalPostAsXml
Run Code Online (Sandbox Code Playgroud)

但是当下一个测试运行时,当它尝试执行RestClient.postAsXml时,它会遇到StackOverflowError:

at groovy.lang.Closure.call(Closure.java:282)
Run Code Online (Sandbox Code Playgroud)

它看起来像RestClient.postAsXml递归指向自身.重置模拟静态方法的正确方法是什么?

Tod*_*one 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
}
Run Code Online (Sandbox Code Playgroud)

如果你正在使用JUnit4,你可以@AfterClass在这种情况下使用,这可能更有意义.


Noe*_*Yap 1

schmolly159 的上述提示让我找到了以下解决方案:

    def originalPostAsXml = RestClient.metaClass.getMetaMethod('postAsXml', [String, String] as Class[])
Run Code Online (Sandbox Code Playgroud)

然后重置方法:

    RestClient.metaClass.'static'.postAsXml = { String uriPath, String xml ->
        originalPostAsXml.invoke(delegate, uriPath, xml)
    }
Run Code Online (Sandbox Code Playgroud)