我决定使用 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/