如何在groovy(Spock)中测试已创建和预期的文件树? 现在,我使用Set来指定要获取的路径,并以这种方式收集实际路径:
Set<String> getCreatedFilePaths(String root) {
Set<String> createFilePaths = new HashSet<>()
new File(root).eachFileRecurse {
createFilePaths << it.absolutePath
}
return createFilePaths
}
但是测试的可读性不是很好。 在常规情况下是否可以将期望的路径写成树,然后将其与实际值进行比较
例如,预期:
region:
usa:
new_york.json
california.json
europe:
spain.json
italy.json
实际将转换为这种树。
答案 0 :(得分:1)
不确定是否可以使用内置的递归方法。当然有强大的功能,但这是您可以使用的标准递归代码:
def path = new File("/Users/me/Downloads")
def printTree(File file, Integer level) {
println " " * level + "${file.name}:"
file.eachFile {
println " " * (level + 1) + it.name
}
file.eachDir {
printTree(it, level + 1)
}
}
printTree(path, 1)
打印出您描述的格式
答案 1 :(得分:1)
您可以构建自己的解析器,也可以使用Groovy的内置JSON解析器:
package de.scrum_master.stackoverflow
import groovy.json.JsonParserType
import groovy.json.JsonSlurper
import spock.lang.Specification
class FileRecursionTest extends Specification {
def jsonDirectoryTree = """{
com : {
na : {
tests : [
MyBaseIT.groovy
]
},
twg : {
sample : {
model : [
PrimeNumberCalculatorSpec.groovy
]
}
}
},
de : {
scrum_master : {
stackoverflow : [
AllowedPasswordsTest.groovy,
CarTest.groovy,
FileRecursionTest.groovy,
{
foo : [
LoginIT.groovy,
LoginModule.groovy,
LoginPage.groovy,
LoginValidationPage.groovy,
User.groovy
]
},
LuceneTest.groovy
],
testing : [
GebTestHelper.groovy,
RestartBrowserIT.groovy,
SampleGebIT.groovy
]
}
}
}"""
def "Parse directory tree JSON representation"() {
given:
def jsonSlurper = new JsonSlurper(type: JsonParserType.LAX)
def rootDirectory = jsonSlurper.parseText(jsonDirectoryTree)
expect:
rootDirectory.de.scrum_master.stackoverflow.contains("CarTest.groovy")
rootDirectory.com.twg.sample.model.contains("PrimeNumberCalculatorSpec.groovy")
when:
def fileList = objectGraphToFileList("src/test/groovy", rootDirectory)
fileList.each { println it }
then:
fileList.size() == 14
fileList.contains("src/test/groovy/de/scrum_master/stackoverflow/CarTest.groovy")
fileList.contains("src/test/groovy/com/twg/sample/model/PrimeNumberCalculatorSpec.groovy")
}
List<File> objectGraphToFileList(String directoryPath, Object directoryContent) {
List<File> files = []
directoryContent.each {
switch (it) {
case String:
files << directoryPath + "/" + it
break
case Map:
files += objectGraphToFileList(directoryPath, it)
break
case Map.Entry:
files += objectGraphToFileList(directoryPath + "/" + (it as Map.Entry).key, (it as Map.Entry).value)
break
default:
throw new IllegalArgumentException("unexpected directory content value $it")
}
}
files
}
}
请注意:
我使用new JsonSlurper(type: JsonParserType.LAX)
是为了避免在JSON结构中引用每个单个String。如果文件名中包含空格或其他特殊字符,则必须使用"my file name"
之类的东西。
在rootDirectory.de.scrum_master.stackoverflow.contains("CarTest.groovy")
中,您可以看到如何使用.property
语法与解析的JSON对象图进行很好的交互。您可能会喜欢或不喜欢,是否需要。
递归方法objectGraphToFileList
将已解析的对象图转换为文件列表(如果您喜欢一个集合,请对其进行更改,但是File.eachFileRecurse(..)
不应产生任何重复,因此该集合不会需要。
如果您不喜欢JSON中的括号等,仍可以构建自己的解析器。
您可能想添加另一种实用程序方法,以从经过验证的目录结构中创建一个类似于给定字符串的JSON字符串,因此编写类似测试时的工作量就减少了。
答案 2 :(得分:0)
经过修改的Bavo Bruylandt答案用于收集文件树路径,并对它进行排序以不关心文件的顺序。
def "check directory structure"() {
expect:
String created = getCreatedFilePaths(new File("/tmp/region"))
String expected = new File("expected.txt").text
created == expected
}
private String getCreatedFilePaths(File root) {
List paths = new ArrayList()
printTree(root, 0, paths)
return paths.join("\n")
}
private void printTree(File file, Integer level, List paths) {
paths << ("\t" * level + "${file.name}:")
file.listFiles().sort{it.name}.each {
if (it.isFile()) {
paths << ("\t" * (level + 1) + it.name)
}
if (it.isDirectory()) {
collectFileTree(it, level + 1, paths)
}
}
}
预期文件以这种方式用indent(\ t)放入Expect.txt文件中:
region:
usa:
new_york.json
california.json
europe:
spain.json
italy.json