0

I could not get it to work. It's like the method is not mocked.

Are there alternative groovy testing frameworks that work better to mock static Java methods?

Update 02/Mar/2011: Adding code:

I am actually trying to mock the Scala XML.loadXml (I am trying Groovy for unit testing) class:

This is my test case:

// ContentManagementGatewayTest.groovy
class ContentManagementGatewayTest extends GMockTestCase
{
  void testGetFileList()
  { 
      // Preparing mocks code will go here, see below

      play {
           GetFileGateway gateway = new GetFileGateway();
           gateway.getData();
      }
  }
}

// GetFileGateway.scala
class GetFileGateway {
    def getData() 
    {  
         // ...
         val xmlData = XML.loadData("file1.txt");
    }
}

I tried testing using both gmock and metaClass:

// metaClass:
XML.metaClass.'static'.loadFile = {file ->
      return "test"
}

// gmock:
def xmlMock = mock(XML)
xmlMock.static.loadFile().returns(stream.getText())
mbdev
  • 6,343
  • 14
  • 46
  • 63

3 Answers3

3

You can do this using Groovy (metaprogramming), you don't need any additional libraries. Here's a (stupid) example, that overrides Collections.max such that it always returns 42. Run this code in the Groovy console to test it.

// Replace the max method with one that always returns 42
Collections.metaClass.static.max = {Collection coll ->
  return 42
}  

// Test it out, if the replacement has been successful, the assertion will pass
def list = [1, 2, 3]
assert 42 == Collections.max(list)

Update

You mentioned in a comment that my suggestion didn't work. Here's another example that corresponds to the code you've shown in your question. I've tested it in the Groovy console and it works for me. If it doesn't work for you, tell me how your testing differs from mine.

Math.metaClass.static.random = {-> 0.5}
assert 0.5 == Math.random()
Dónal
  • 185,044
  • 174
  • 569
  • 824
  • Turns out this is the result of XML being Object in Scala. and not related to gmock ability to mock statics. – mbdev Mar 02 '11 at 15:43
2

The documentation for GMock seems to show that you can just do:

Mocking static method calls and property call is similar to standard method calls, just add the static keyword:

def mockMath = mock(Math)
mockMath.static.random().returns(0.5)

play {
  assertEquals 0.5, Math.random()
}
tim_yates
  • 167,322
  • 27
  • 342
  • 338
  • Well, I think it works with mocking static methods inside groovy. See here: http://hamletdarcy.blogspot.com/2008/04/testing-java-from-groovy-2.html – mbdev Mar 02 '11 at 11:42
2

Scala doesn't have static methods, so it is no wonder you couldn't mock one -- it doesn't exist.

The method loadXml to which you refer is found on the XML object. You can get that object from Java with scala.XML$.MODULE$, but, since objects are singleton, its class is final.

Alas, loadXML is defined on the class XMLLoader, which the object XML extends, not on the object XML itself. So you can simply do a normal mock of XMLLoader. It will lack a few methods, but perhaps it will do all you need.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681