gpt4 book ai didi

java - mock groovy new File.eachFile()

转载 作者:行者123 更新时间:2023-11-30 05:06:08 25 4
gpt4 key购买 nike

我在模拟 file.eachFile() {} 时遇到问题。

我正在尝试模拟从 file.eachFile{} 返回的文件 - 我不想实际测试驱动器上真实目录的内容。

我不明白如何使用 Spock 来实现这一点(据我所知,它更多地用于模拟验证)。

因此,我决定使用“原生”Groovy 模拟功能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);
}

对于所有模拟这个的编码尝试,我已经有点模糊了:)

我设法到达该方法(没有运行时异常),但无法实际看到预先定义的文件列表的注入(inject)。

测试的方法是(为了简单起见):

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() (它没有将模拟传递给方法,它期望模拟在“use” block 中实例化)?

测试中的代码如下所示:

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,所以我还在适应它。谢谢

最佳答案

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"
}

他是对的。正如我所说,我使用 Groovy 的时间并不长(Spock 也没有)。

“我猜这是因为代码中没有直接使用 File.eachFile() (它没有将模拟传递给方法,它期望模拟在“use” block 中实例化)? ”

测试中的代码如下所示:

when:

mock.use {
folderValidator.validate(new File("."))
}

then:
folderValidator.listMissingFiles.size == 3

解决方案是简单地在 use block 内实例化模拟类。我认为模拟已实例化并将在方法中传递 - Mockito 的工作方式。

莫基托:

File pathScripts;
pathScripts = mock(File.class);
when(pathScripts.list()).thenReturn(listFiles);

someObject.someTestingMethod(pathScripts)

proxyInstance 方法是模拟类,但是使用适当的构造函数参数!

def mock = new MockFor(File)
mock.demand.eachFile {func ->
[new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each { func(it) }
}

def mockProxy = mock.proxyInstance(".")

mockProxy.eachFile {file ->
println "$file"
}

而且,最大的错误是我的模拟方法中缺少闭包:

mockFile.demand.eachFile { **??** [new File("script1.sql"), new File("script2.syn"), new File("script3.grt")].each {**?**(it)}} 

所以,谢谢你,tim_yates

关于java - mock groovy new File.eachFile(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5030155/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com