You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spock中模拟Groovy的eachDir闭包方法?

在Spock中正确模拟File类的eachDir闭包方法

你碰到的问题核心在于:eachDir不是java.io.File类的原生方法,而是Groovy GDK给File类添加的扩展方法,所以直接在Mock(File)里定义eachDir()的行为是行不通的。不过我们可以通过mock它底层依赖的原生方法来实现需求,下面是具体的解决办法:

解决方案思路

Groovy的File.eachDir()方法本质上是调用了File.listFiles(FileFilter),筛选出目录类型的文件后,依次传入闭包执行。所以我们只需要mocklistFiles()方法返回预先准备好的mock子目录数组,eachDir()就能自动按照预期工作了。

正确的Mock代码示例

def mockSubdirs = []
mockSubdirs << Mock(File) {
    getName() >> 'some subdir'
    lastModified() >> 2000
    isDirectory() >> true // 关键:标记为目录,这样eachDir才会识别它
}
// 可以再加一个子目录示例
mockSubdirs << Mock(File) {
    getName() >> 'another subdir'
    lastModified() >> 3000
    isDirectory() >> true
}

File mockParentDir = Mock(File) {
    getName() >> 'parent dir'
    // mock原生的listFiles方法,返回我们的mock子目录数组
    listFiles() >> mockSubdirs.toArray(new File[0])
}

cut.myDirectory = mockParentDir

验证测试的应用代码示例

假设你的应用代码是这样遍历目录的:

def dirNames = []
myDirectory.eachDir { dir ->
    dirNames << dir.name
}

那么在测试里你可以这样断言:

expect:
dirNames == ['some subdir', 'another subdir']

额外注意点

  • 一定要给mock的子目录设置isDirectory() >> true,因为eachDir只会筛选出目录类型的文件,否则这些mock文件会被忽略。
  • 对于GDK的扩展方法,优先mock它依赖的原生JDK方法,这比直接mock扩展方法要简单可靠得多,因为扩展方法通常是基于原生方法实现的。

内容的提问来源于stack exchange,提问作者mike rodent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:47:11