Я пытаюсь смоделировать новый файл, созданный в цикле.Упрощенный пример:
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), любые идеи, как издеватьсяэто, не используя дополнительные библиотеки и не заканчивая бесполезными классами?
Спасибо.