Spock 测试 - 变量从 new 运算符获取空值

Spock testing - variables getting null value from the new operator

下面是我的测试代码,

def 'test write then update with commit after all operations parallely'() {
    given:
    def outputPath = "writeThenUpdateWithCommitAfterAllOperationsParallely.csv"
    csvManipulator = new CsvManipulator(RESOURCE_PATH, outputPath, FIELD_COUNT, 0
            , new ResourceReaderProvider(), new FileWriterProvider())

    when:
    GParsPool.withPool 100, {
        (0..LOOP-1).eachParallel { row ->
            writeThenUpdate(row, false)
        }
    }
    csvManipulator.commit()

    then:
    Reader reader = new FileReader(outputPath)
    def outputRawCsv = IOUtils.toString(reader)
    expectedRawCsv == outputRawCsv

    cleanup:
    reader.close()
    Files.delete(Paths.get(outputPath))
}

简而言之,在每一行的调试模式下,我看到所有变量 outputPathcsvManipulator ... 和 reader(在 then 块中)是全部 null.

因此,测试最终在 NullPointerException 发生在关闭 null reader 期间发生。

它在调试模式下的样子:(你可以看到所有变量都是空的)

会发生什么?

根据 Spock 文档:"The when and then blocks always occur together. They describe a stimulus and the expected response. Whereas when blocks may contain arbitrary code, then blocks are restricted to conditions, exception conditions, interactions, and variable definitions. A feature method may contain multiple pairs of when-then blocks." Spock blocks

这两行:

Reader reader = new FileReader(outputPath)
def outputRawCsv = IOUtils.toString(reader)

需要在上面的when块如下图:

def 'test write then update with commit after all operations parallely'() {
    given:
    def outputPath = "writeThenUpdateWithCommitAfterAllOperationsParallely.csv"
    csvManipulator = new CsvManipulator(RESOURCE_PATH, outputPath, FIELD_COUNT, 0
            , new ResourceReaderProvider(), new FileWriterProvider())

    when:
    GParsPool.withPool 100, {
        (0..LOOP-1).eachParallel { row ->
            writeThenUpdate(row, false)
        }
    }
    csvManipulator.commit()
    Reader reader = new FileReader(outputPath)
    def outputRawCsv = IOUtils.toString(reader)

    then:
    expectedRawCsv == outputRawCsv

    cleanup:
    reader.close()
    Files.delete(Paths.get(outputPath))
}

我也会考虑使用 Leonard 建议的方法阅读文件:

def outputRawCsv = new File(outputPath).text

添加所有内容:

def 'test write then update with commit after all operations parallely'() {
    given:
    def outputPath = "writeThenUpdateWithCommitAfterAllOperationsParallely.csv"
    csvManipulator = new CsvManipulator(RESOURCE_PATH, outputPath, FIELD_COUNT, 0
            , new ResourceReaderProvider(), new FileWriterProvider())

    when:
    GParsPool.withPool 100, {
        (0..LOOP-1).eachParallel { row ->
            writeThenUpdate(row, false)
        }
    }
    csvManipulator.commit()
    def outputRawCsv = new File(outputPath).text

    then:
    expectedRawCsv == outputRawCsv

    cleanup:
    reader.close()
    Files.delete(Paths.get(outputPath))
}

如果这不起作用需要 http://whosebug.com/help/mcve