java - 使用 Spock 的 Groovy 模拟文件工厂

标签 java groovy mocking spock

我决定使用 File Factory 来模拟 File 对象的构造。

class FileClass {

  def basePath
  def listObjects = []

  def createFilePerObject() {
    listObjects.each {currentObject ->
      // Use some other libraries for mocking(cant run PowerMockito, Gareth Davis adviced me to use JMockit)

      // File currentFile = new File("${basePath.toString()}/${currentObject.objectName}")

      //File factory(The simplest of the solutions)...
      File currentFile = FileFactory.makeFile("${basePath.toString()}/${currentObject.objectName}")

      currentFile.write currentObject.objectContent   //Verify this behaviour!!
    }
  }

}

class SimpleObject {
  String objectName
  String objectContent
}

//Really simple
class FileFactory {
  def static makeFile(String pathFileName) {
    return new File(pathFileName);
  }
}

和测试:

class FileClassTest extends Specification {

  FileClass fileClass

  def "test simple object"() {

    def listObjects = []

    SimpleObject object1 = new SimpleObject(objectName: "First object", objectContent: "First object content")
    SimpleObject object2 = new SimpleObject(objectName: "Second object", objectContent: "Second object content")
    SimpleObject object3 = new SimpleObject(objectName: "Third object", objectContent: "Third object content")
    SimpleObject object4 = new SimpleObject(objectName: "Fourth object", objectContent: "Fourth object content")

    listObjects << object1
    listObjects << object2
    listObjects << object3
    listObjects << object4

    fileClass = new FileClass(listObjects: listObjects, basePath: ".")

    def mockFile = Mock(File)

    def mockFileFactory = new MockFor(FileFactory)
    mockFileFactory.demand.makeFile {mockFile}    //Return the mocked file...

    when:
    mockFileFactory.use {
      fileClass.createFilePerObject()
    }

    then:
    1 * mockFile.write(_)
  }

}

问题是它因 NullPointerException 而失败!?

使用我得到的调试器:

currentFile.write currentObject.objectContent   //Verify this behaviour!!

而且,经过验证,“当前文件”确实是测试中指定的模拟文件。 “currentObject.objectContent”不为空,“currentFile”不为空。

突然,它跳转到 BaseSpecRunner.java 这个方法:

protected Object invokeRaw(Object target, MethodInfo method, Object[] arguments) {
    if (method.isStub()) return null;

    try {
      return method.getReflection().invoke(target, arguments);
    } catch (InvocationTargetException e) {
      //Here it fails!
      runStatus = supervisor.error(new ErrorInfo(method, e.getTargetException()));
      return null;
    } catch (Throwable t) {
      Error internalError =
          new InternalSpockError("Failed to invoke method '%s'", t).withArgs(method.getReflection().getName());
      runStatus = supervisor.error(new ErrorInfo(method, internalError));
      return null;
    }
  }

“InvocationTargetException 是一个已检查的异常,它包装了由调用的方法或构造函数抛出的异常。”。太好了。

有什么想法吗?

谢谢。

最佳答案

Spock 目前不支持像 File.write() 这样由 Groovy 动态添加但不存在于类中的模拟方法。您可以改用 Groovy 的 MockFor 来解决这个问题,就像您对其他模拟所做的那样。

InvocationTargetException 是一个内部 Groovy 异常。它包装了您看到的 NullPointerException。 Spock 足够聪明,可以为您解包异常。

关于java - 使用 Spock 的 Groovy 模拟文件工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5105893/

相关文章:

java - 为什么最新版本的 apache-cassandra-X.X.X.jar 中没有 CqlStorage 类

java - logback:使用 groovy 配置时如何区分测试和主要日志记录?

python - 仅模拟对象上的单个方法

java - 重置 Mockito spy

java - Properties.loadFromXML() 和 Properties.storeToXML() 方法的目的是什么?

Java DBUnit AmbigouslyTableNameException 错误抛出

web-services - 调用测试用例不起作用

html - 在 Groovy 1.7 中使用包含混合内容的 HTML 构建器的正确语法是什么?

django - 查看单元测试中的模拟表单

Java ActionCommand 相当于 FocusListener