Groovy mocking Файловый конструктор, проверьте запись на вновь созданные файлы - PullRequest
3 голосов
/ 24 февраля 2011

Я пытаюсь смоделировать новый файл, созданный в цикле.Упрощенный пример:

class FileClass {

  def basePath
  def listObjects = []

  def createFilePerObject() {
    listObjects.each {currentObject ->
      File currentFile = new File("${basePath.toString()}/${currentObject.objectName}")

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

}

class SimpleObject {
  String objectName
  String objectContent
}

И тест:

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 dummyFile = new MockFor(File)
    def mockFile = new MockFor(File, true)  //Intercept constructor call

    mockFile.demand.with {
      File() {dummyFile}
    }

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

    then:
    1 * mockFile.write(_)
  }

}

Итак, как вы можете видеть, я пытаюсь убедиться, что в новых файлах действительно что-то написано.

И я получаю следующую ошибку:

MockFor with constructor interception enabled is only allowed for Groovy objects but found: java.io.File

Итак, File, как я понимаю, расширен в groovy GDK (Groovy JDK) и имеет дополнительные (и очень полезные) методы.Но Groovy пытается насмехаться над java.io.File.

И, следуя логике ошибки, я решил на самом деле переопределить конструктор File следующим образом:

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(basePath: ".", listObjects: listObjects)

    def mockFile = new MockFor(File)

    File.metaClass.constructor << {String filePath -> mockFile } //Return the mocked file, so it can be verified

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

    then:
    1 * mockFile.write(_)
  }

}

И получил предупреждениечто конструктор уже существует (я полагаю, я не могу его перефразировать):

groovy.lang.GroovyRuntimeException: Cannot add new constructor for arguments [[class java.lang.String]]. It already exists!

Итак, одна из идей заключается в том, чтобы на самом деле насмехаться над Файловой фабрикой, которая создаст новые объекты File в цикле.Тем не менее, фабрика, мягко говоря, бесполезна - она ​​будет использоваться только для того, чтобы иметь возможность проверить создание файла.

Итак, PowerMock не работает (не могу загрузить PowerMockRunner), любые идеи, как издеватьсяэто, не используя дополнительные библиотеки и не заканчивая бесполезными классами?

Спасибо.

1 Ответ

1 голос
/ 24 февраля 2011

Могу ли я предложить альтернативный, не чистый подход к тестированию.

Для этого одного теста создайте временный каталог, установите basePath в своем объекте теста и дайте тесту фактически записать файл. Ваши утверждения, очевидно, прочитали файл, чтобы проверить результат, но это был бы полный тест без попытки макетировать классы JDK. Тестовый демонтаж может затем очистить временный каталог.

Если вы действительно настроены на чистое тестирование модулей памяти, я боюсь, что вам, возможно, придется использовать JMockIt , который, если вы сможете разобраться с этим, и документация может высмеивать практически все, включая детали JDK.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...