Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I reset a mocked static method in Groovy?

Tags:

groovy

I have the following in the test setup:

    def originalPostAsXml = RestClient.&postAsXml

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

and in the test cleanup:

    RestClient.metaClass.'static'.postAsXml = originalPostAsXml

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

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

It looks like RestClient.postAsXml recursively points to itself. What's the right way to reset a mocked-out static method?

like image 786
Noel Yap Avatar asked Dec 01 '11 22:12

Noel Yap


2 Answers

In a unit test, I often set the metaclass to null in the tearDown() which seems to allow the class to work as it did originally without my modifications.

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 are using JUnit4 you can use @AfterClass instead in this case which makes more sense perhaps.

like image 189
Todd W Crone Avatar answered Sep 21 '22 03:09

Todd W Crone


I find that simply 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
}
like image 21
dafunker Avatar answered Sep 22 '22 03:09

dafunker