我正在尝试使用 Specs2 编写以下规范,但似乎无法使其工作,编译器总是抱怨“Unit => org.specs2.execute.Result 没有可用的隐式视图”。
这是测试源:
"generate the correct output when merging an extraction" in {
val source = new File("src/test/resources/sample-docs/text-and-image-on-page-2.pdf")
val output = this.extractor.extract(source)
val pdfGenerator = new ITextPdfGenerator()
val processor = new ExecutableProcessor()
val ocrInput = IOUtils.createTempFile("ocr_input", "pdf")
val ocrOutput = IOUtils.createTempFile("ocr_output", "pdf")
deleteWhenDone[MatchResult[Any]](output.getFullTextFile, ocrInput, ocrOutput) ( {
pdfGenerator.generatePdf(source, ocrInput, output.getPagesWithImages)
processor.process(ocrInput, ocrOutput)
this.extractor.mergeExtraction(output, ocrOutput)
IOUtils.readFile(output.getFullTextFile) === """sample text on line 1 page 1 sample text on line 2 page 1 sample text on line 1 page 3 sample text on line 2 page 3 """
})
}
完成后删除功能如下:
def deleteWhenDone[T]( files : File* ) ( fn : => T ) {
try {
fn
} finally {
IOUtils.deleteFiles( files )
}
}
如果此行位于规范的末尾,则它确实有效:
IOUtils.readFile(output.getFullTextFile) === "sample text on line 1 page 1 sample text on line 2 page 1 sample text on line 1 page 3 sample text on line 2 page 3 "
为什么会这样失败?我该怎么做才能继续使用闭包并让测试编译?
编辑
将deleteWhenDone调用更改为:
deleteWhenDone[Result](output.getFullTextFile, ocrInput, ocrOutput) ( {
pdfGenerator.generatePdf(source, ocrInput, output.getPagesWithImages)
processor.process(ocrInput, ocrOutput)
this.extractor.mergeExtraction(output, ocrOutput)
IOUtils.readFile(output.getFullTextFile) === "sample text on line 1 page 1 sample text on line 2 page 1 sample text on line 1 page 3 sample text on line 2 page 3 "
})
但是还是不行。
编辑2
感谢拉斐尔的回答,使其工作的最终代码是:
def deleteWhenDone[T]( files : File* ) ( fn : => T ) : T = {
try {
fn
} finally {
IOUtils.deleteFiles( files )
}
}
我错过了方法返回类型。谢谢!
deleteWhenDone
函数的结果类型为Unit,它与in
参数的预期类型不兼容。您可以通过在定义中添加等号来将其更改为返回 T
:
def deleteWhenDone[T]( files : File* ) ( fn : => T ) = {
try {
fn
} finally {
IOUtils.deleteFiles( files )
}
}
in 方法定义如下:
def in[T <% Result](r: => T): Example
因此它需要一个代码块作为参数,其返回类型派生自 Result 或可以隐式转换为 Result。如果您在测试结束时编写 Success(),它将编译。
你也可以这样做:
implicit def anyToSuccess[T](a: T): org.specs2.execute.Result = success