Below is my test code,
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))
}
In short, during debugging mode at each line, I saw all variables outputPath
, csvManipulator
... and reader
(in the then
block) are all null.
Hence, the test ends up in the NullPointerException
occurs during closing the null reader.
And that how it looks like in debugging mode: (you can see all the variables are null)
What happens?
According to the Spock Documentation: "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
These two lines:
Reader reader = new FileReader(outputPath)
def outputRawCsv = IOUtils.toString(reader)
Need to be in the above when block as shown below:
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))
}
I would also consider reading the file in using the method Leonard suggested:
def outputRawCsv = new File(outputPath).text
Adding everything in:
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))
}
If this doesn't work going to need the http://stackoverflow.com/help/mcve