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 平台上却是正常的多行!

深入解析Linux下 的问题

解决方案

/**
 * 读取多行数据的问题。
 *
 * @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 "";
    }
}
原文地址:https://www.cnblogs.com/kendoziyu/p/14353184.html