How to reset a mocked static method in Groovy?

I have the following in a test setup:

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

and in test cleaning:

  RestClient.metaClass.'static'.postAsXml = originalPostAsXml 

But when the following test runs, when it tries to execute RestClient.postAsXml, it runs in a StackOverflowError:

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

RestClient.postAsXml seems to recursively point to itself. What is the correct way to reset the exhausted static method?

+6
source share
3 answers

In unit test, I often set the metaclass to null in tearDown() , which apparently allows the class to work the way it was originally unchanged.

Example:

 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 } 

If you use JUnit4, you can use @AfterClass instead in this case, which makes more sense.

+6
source

I believe just setting <Class>.metaClass = null works for me.

Spock example:

 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
source
hint

schmolly159 led me to the following solution:

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

then reset method:

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

Source: https://habr.com/ru/post/902877/


All Articles