Spock数据驱动测试:首个用例后临时目录相关路径为空致失败
Spock数据驱动测试中第二个用例临时目录相关路径为空的问题
问题原因
核心问题出在AsyncTestUtils的实现逻辑:
- 当前的
awaitUntil和andThen方法接收的是Boolean类型参数,这个参数会在方法调用时立即计算出固定结果,后续PollingConditions每次轮询都只会检查这个静态布尔值,不会重新执行条件判断逻辑。 - 第一个用例执行时,service刚完成文件写入,tempDir此时非空,
!isEmpty(tempDir)直接计算为true,轮询直接通过;后续检查dataSavedDir时,可能刚好文件已经移动完成,!isEmpty(dataSavedDir)也为true,所以用例正常通过。 - 第二个用例执行时,初始状态下dataSavedDir还未创建,
!isEmpty(dataSavedDir)立即计算为false,后续轮询一直检查这个固定的false值,最终超时失败,表现为dataSavedDir为空。 - 无论是用
@TempDir还是手动创建临时目录,只要AsyncTestUtils的逻辑不变,问题都会存在,临时目录配置本身不是直接原因。
解决方案
修改AsyncTestUtils,让它接收Groovy闭包作为条件,这样每次轮询时都会重新执行闭包获取最新的目录状态:
trait AsyncTestUtils<T extends AsyncTestUtils<T>> { PollingConditions pollingConditions = new PollingConditions() T awaitUntil(Closure<Boolean> condition, String failMessage = "Assertion failed in awaitUntil") { pollingConditions.within(10) { assert condition.call() : failMessage } return (T) this } T andThen(Closure<Boolean> condition, String failMessage = "Assertion failed in andThen") { pollingConditions.within(10) { assert condition.call() : failMessage } return (T) this } }
然后在测试代码中,传递闭包而非直接计算布尔值:
then: Path dataSavedDir = dataDir.resolve("simulations/${simulationId}/${directoryName}") awaitUntil({ !isEmpty(tempDir) }, "File exists in a tempDir") .andThen({ !isEmpty(dataSavedDir) }, "File exists in an appropriate directory of a simulation") .andThen({ isEmpty(tempDir) }, "tempDir is empty")
额外注意点
- 确保
isEmpty()方法实现正确,能处理目录不存在的情况(此时应返回true)。 - 由于
simulationId是@Shared的,多个用例会共用同一个ID,需确认被测的StorageService支持同一ID下创建不同子目录(如plots、geometry)的逻辑无冲突。
内容的提问来源于stack exchange,提问作者rafal.sz
相关产品推荐
相关产品推荐

