我在测试设置中有以下内容:
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 :(得分:6)
在单元测试中,我经常将元类设置为null
中的tearDown()
,这似乎允许类在没有我修改的情况下像原来一样工作。
示例:
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
,这可能更有意义。
答案 1 :(得分:2)
我发现简单地设置<Class>.metaClass = null
对我有用。
Spock示例:
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
}
答案 2 :(得分: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)
}