junit测试用例从src/test/resources下的txt文件读取多行数据并随机选择一行 踩坑背景 从测试资源文件中读取字符串 随机选取一行 解决方案
我遇到的这个问题,在 windows 平台上,测试用例运行正常,但是到了 linux 平台上构建时,测试用例总是运行失败!
而且因为自动构建又不能打断点,所以只好一点点地分析问题所在!
我的需求是这样的:
-
首先,在 src/test/resources 文件夹下面创建 xxxx.txt 文件
-
接着,从 xxxx.txt 文件中读取字符串
-
最后,把字符串按行分割,并且过滤掉一些不需要的行(比如注释行)
但是郁闷的是,我在 windows 上随机选择的一行数据总是我期望的,但是在 linux 平台上随机选择的一行总是空字符串
从测试资源文件中读取字符串
protected String getContentFromResource(String filePath) throws IOException, URISyntaxException {
URL resource = Thread.currentThread().getContextClassLoader().getResource(filePath);
URI uri = resource.toURI();
byte[] bytes = Files.readAllBytes(Paths.get(uri));
String result = new String(bytes, StandardCharsets.UTF_8);
log.info("Get content from resource is {} blank: {}",
StringUtils.isNotBlank(result) ? "not" : "", uri.getPath());
return result;
}
protected int randomInRange(int low, int high) {
return ThreadLocalRandom.current().nextInt(low, high);
}
一开始总怀疑是读取不到数据,但是尝试多次后发现,在 linux 系统上测试用例是可以正常读取到文件中的数据!
随机选取一行
protected String randomLine(String lines, Predicate<String> predicate) {
List<String> validLines = Arrays.stream(lines.split("
"))
.filter(predicate).collect(Collectors.toList());
if (validLines.size() == 0) {
return "";
}
int index = randomInRange(0, validLines.size());
if (index < validLines.size()) {
return validLines.get(index);
} else {
return "";
}
}
找了好久才发现问题就出在 lines.split("
")
。txt文件在 windows 平台上行尾是
, 但是到了 linux 平台上,行尾却是
。
同样是对从 txt 文件中读取到字符串调用 split("
")
,结果在 linux 平台上总是只得到一行,但在 windows 平台上却是正常的多行!
解决方案
/**
* 读取多行数据的问题。
*
* @param lines 多行数据字符串
* @return 分割后的多行
*/
protected List<String> readLines(String lines) {
List<String> result = new LinkedList<>();
try (StringReader reader = new StringReader(lines);
BufferedReader buffer = new BufferedReader(reader)) {
String line;
// 按行读取字符串
while ((line = buffer.readLine()) != null) {
result.add(line);
}
} catch (IOException e) {
log.error("IO Exception occurred.", e);
}
return result;
}
然后再把 Arrays.stream(lines.split("
"))
替换成 readLines(lines).stream()
修改后的 randomLine 代码如下:
protected String randomLine(String lines, Predicate<String> predicate) {
List<String> validLines = readLines(lines).stream()
.filter(predicate).collect(Collectors.toList());
if (validLines.size() == 0) {
return "";
}
int index = randomInRange(0, validLines.size());
if (index < validLines.size()) {
return validLines.get(index);
} else {
return "";
}
}