如何在Groovy中重置模拟静态方法?
我在测试设置中有以下内容:如何在Groovy中重置模拟静态方法?,groovy,Groovy,我在测试设置中有以下内容: def originalPostAsXml = RestClient.&postAsXml RestClient.metaClass.'static'.postAsXml = { String uriPath, String xml -> return 65536 } 在测试清理中: RestClient.metaClass.'static'.postAsXml = originalPo
def originalPostAsXml = RestClient.&postAsXml
RestClient.metaClass.'static'.postAsXml = {
String uriPath, String xml ->
return 65536
}
在测试清理中:
RestClient.metaClass.'static'.postAsXml = originalPostAsXml
但是,当下一个测试运行时,当它尝试执行RestClient.postAsXml时,它会遇到StackOverflower错误:
at groovy.lang.Closure.call(Closure.java:282)
看起来RestClient.postAsXml递归地指向它自己。重置模拟静态方法的正确方法是什么?上面schmolly159的提示让我找到了以下解决方案:
def originalPostAsXml = RestClient.metaClass.getMetaMethod('postAsXml', [String, String] as Class[])
然后重置方法:
RestClient.metaClass.'static'.postAsXml = { String uriPath, String xml ->
originalPostAsXml.invoke(delegate, uriPath, xml)
}
在单元测试中,我经常在
tearDown()
中将元类设置为null
,这似乎允许类在没有修改的情况下像最初那样工作
例如:
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
,这可能更有意义。我发现简单地设置.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
}
这里有一个类似的问题:您可以重置元类-看到这个问题,它有答案,谢谢-我也在使用Spock,并将Class.metaclass.static.方法设置为null不起作用,但将Class.metaclass设置为null起作用。