【发布时间】:2011-06-29 03:29:58
【问题描述】:
我在模拟 file.eachFile() {} 时遇到问题。
我正在尝试模拟从 file.eachFile{} 返回的文件 - 我不想实际测试驱动器上真实目录的内容。
我不知道如何使用 Spock 来实现这一点(据我所知,它更多地用于模拟验证)。
所以,我决定使用“原生”Groovy mock 功能 和 MOP 功能。 没有运气。
例如(我必须删除文件类型才能将对象传递给测试功能):
def mockFile = new MockFor(java.io.File)
mockFile.demand.eachFile {[new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each {it}}
或者(使用元类):
File mockFile = new File("irrelevant_path")
mockFile.metaClass.eachFile = {[new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each {it}}
我的 eachFile 方法定义为:
public static void eachFile(final File self, final Closure closure) throws FileNotFoundException, IllegalArgumentException {
eachFile(self, FileType.ANY, closure);
}
对于所有模拟这个的编码尝试,我已经有点模糊了:)
我设法到达了方法(没有运行时异常),但实际上无法看到预先定义的文件列表的注入。
测试的方法是(为简单起见):
folderSourceScripts.eachFile {File currentFile -> ..... }
在 Java 中,Mockito 会在一分钟内完成此操作,但我在某处看到与 Groovy 集成存在一些问题。模拟类时出现问题,因为 Groovy 调用了元类。
我看到了这个here。
tim_yates 写道:
def mock = new MockFor(File)
mock.demand.eachFile {
[new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each { (it) }
}
mock.use {
new File('.').eachFile {file ->
println "$file"
}
脚本有效,但在测试中使用时有一个问题。
正如我所提到的,我正在使用 Spock,并且文件变量是在一个方法中传递的。 因此,以您编写它的方式使用它会导致:
groovy.lang.MissingMethodException: No signature of method: groovy.mock.interceptor.MockFor.eachFile() is applicable for argument types: ...
我猜那是因为在代码中没有直接使用 File.eachFile()(它没有将模拟传递给方法,它希望模拟在“使用”块中实例化)?
测试中的代码如下所示:
when:
mock.use {
folderValidator.validate(mock)
}
then:
folderValidator.listMissingFiles.size == 3
应该将模拟传递给方法的 proxyInstance() 的问题是,如示例所示:
when:
folderValidator.validate(mockProxy)
then:
folderValidator.listMissingFiles.size == 3
mock传递时,groovy无法实例化类,因为它不知道使用哪个构造函数?
org.codehaus.groovy.runtime.metaclass.MethodSelectionException: Could not find which method <init>() to invoke from this list:
private java.io.File#<init>(java.lang.String, int)
private java.io.File#<init>(java.lang.String, java.io.File)
public java.io.File#<init>(java.lang.String)
public java.io.File#<init>(java.net.URI)
public java.io.File#<init>(java.io.File, java.lang.String)
public java.io.File#<init>(java.lang.String, java.lang.String)
理论上它可以工作,但在这个例子中它失败了,也许我编码错了。我两周前开始使用 Groovy,所以我还是习惯了。 谢谢
【问题讨论】: