数据驱动测试中的 Spock 临时目录在第一种情况后失败

问题描述 投票:0回答:1

我正在使用 Spock 测试一些涉及将数据保存到磁盘的代码(Spring 应用程序)。我需要测试多个案例,因此我使用

where:
关键字来计划多个测试案例。测试的代码将一些数据保存到
tempDir
中,然后将其移动到
dataDir
中。

不知何故,无论我如何尝试配置临时目录,无论是通过

@TempDir
还是
Files.createTempDirectory()
,第一个测试都很好通过,而第二个测试失败,因为临时
Path
为空。如果我注释掉任何一个案例,另一个案例就会通过。

可能需要注意的是,tempDir 看起来不错,但由于

dataSavedDir
为空,测试总是失败。

我的测试规格:

class SimulationStorageSpec extends Specification implements StorageDtos, AsyncTestUtils {

    SimulationStorageService service
    @TempDir Path tempDir
    @TempDir Path dataDir
    @Shared String simulationId = "ABC123"

    def setup() {
        service = new SimulationStorageConfiguration().simulationDataStorageService(tempDir.toString(), dataDir.toString())
    }

    def "should accept raw simulation data file and save it"() {
        when:
        service.processAttachment(datafile, dto)
        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")
        and:
        try (InputStream is = Files.newInputStream(dataSavedDir.toFile().listFiles()[0].toPath())) {
            assert DigestUtils.sha256Hex(is) == dto.getFileHash()
        }
        where:
        datafile                    | dto                                   | directoryName
        singleRawPlotData()         | singleRawPlotDto(simulationId)        | "plots"
        singleRawGeometryData()     | singleRawGeometryDto(simulationId)    | "geometry"
    }

AsyncTestUtils(只是链 PollingConditions 的一个特征,测试的代码是异步的):

trait AsyncTestUtils <T extends AsyncTestUtils<T>> {
    PollingConditions pollingConditions = new PollingConditions()

    T awaitUntil(Boolean condition, String failMessage = "Assertion failed in awaitUntil") {
        pollingConditions.within(10) {
            assert condition : failMessage
        }
        return (T) this
    }

    T andThen(Boolean condition, String failMessage = "Assertion failed in andThen") {
        pollingConditions.within(10) {
            assert condition : failMessage
        }
        return (T) this
    }
}

这可能是临时目录配置、我的异步测试代码或其他问题吗?

groovy spock
1个回答
0
投票

特征中的函数接受布尔值:

T awaitUntil(Boolean condition, String failMessage = "Assertion failed in awaitUntil") {
    pollingConditions.within(10) {
        assert condition : failMessage
    }
    return (T) this
}

它们被称为:

awaitUntil(!isEmpty(tempDir), "File exists in a tempDir")
。所以这只是传递一个布尔结果; “断言” 调用
awaitUntil
之前完成。

所以结果已经是注定的;等待这个 结果/断言是无用的。它要么总是立即起作用,要么永远不起作用。

所以你想要的是传递一个“布尔供应商”。和 groovy 最方便的方法是传递一个闭包:

// call passing the thing to check
awaitUntil({!isEmpty(tempDir)}, "File exists in a tempDir")
// accept a function and call it in the `assert`
T awaitUntil(Closure<Boolean> conditionFn, String failMessage = "Assertion failed in awaitUntil") {
    pollingConditions.within(10) {
        assert conditionFn() : failMessage
    }
    return (T) this
}
© www.soinside.com 2019 - 2024. All rights reserved.