可以gmock模拟Java类的静态方法吗?另类?

时间:2011-03-02 08:40:52

标签: java scala groovy gmock

我无法让它发挥作用。这种方法并没有被嘲笑。

是否有替代groovy测试框架更适合模拟静态Java方法?

更新02 / Mar / 2011 :添加代码:

我实际上是在尝试模拟Scala XML.loadXml(我正在尝试使用Groovy进行单元测试)类:

这是我的测试用例:

// 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");
    }
}

我尝试使用gmock和metaClass进行测试:

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

// gmock:
def xmlMock = mock(XML)
xmlMock.static.loadFile().returns(stream.getText())

3 个答案:

答案 0 :(得分:3)

您可以使用Groovy(元编程)执行此操作,您不需要任何其他库。这是一个(愚蠢的)示例,它覆盖Collections.max,使其始终返回42.在Groovy控制台中运行此代码进行测试。

// 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)

更新

您在评论中提到我的建议不起作用。这是另一个与您在问题中显示的代码相对应的示例。我在Groovy控制台中对它进行了测试,它对我有用。如果它不适合您,请告诉我您的测试与我的不同之处。

Math.metaClass.static.random = {-> 0.5}
assert 0.5 == Math.random()

答案 1 :(得分:2)

documentation for GMock似乎表明您可以这样做:

  

模拟静态方法调用和   财产调用类似于标准   方法调用,只需添加静态   关键字:

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

play {
  assertEquals 0.5, Math.random()
}

答案 2 :(得分:2)

Scala没有静态方法,所以难怪你不能模拟它 - 它不存在。

您引用的方法loadXml位于XML 对象上。您可以使用scala.XML$.MODULE$从Java获取该对象,但是,由于对象是单例,因此其类是最终的。

唉,loadXML在类XMLLoader上定义,对象XML扩展,而不是对象XML本身。所以你可以简单地做一下XMLLoader的正常模拟。它缺少一些方法,但也许它可以满足您的所有需求。