如何为使用Scanner读取文件的Java方法编写JUnit单元测试?
问题解答
1. 是否可以复用业务使用的input.txt作为单元测试文件
绝对不建议这么做,原因如下:
- 业务文件内容会随需求迭代频繁变更,会导致单元测试结果不稳定,无法作为代码正确性的校验标准
- 单元测试要求环境隔离、结果可复现,依赖业务环境的外部文件不符合单测原则
- 业务文件通常只有正常业务场景的数据,无法覆盖边界异常场景(比如空文件、格式错误行、字段缺失、特殊字符等测试场景)
2. 编写JUnit测试的方案
2.1 先优化原业务代码的可测试性
你贴的原代码本身存在一个bug:循环中只判断了scan.hasNextLine(),但没有调用scan.nextLine()给line变量赋值,运行会报错。同时原方法硬编码了文件路径,耦合度太高不利于测试,建议调整为传入文件路径参数:
private List<Customer> customerList = new ArrayList<>(); // 重载方法:对外保留原无参方法兼容现有业务 public void scanLocalFile() throws FileNotFoundException { scanLocalFile(new File("input.txt")); } // 抽取带File参数的方法,方便测试时传入自定义测试文件 public void scanLocalFile(File file) throws FileNotFoundException { customerList.clear(); // 每次调用先清空列表,避免历史数据干扰 Scanner scan = new Scanner(file); while (scan.hasNextLine()) { String line = scan.nextLine(); // 补全原代码缺失的行读取逻辑 if (line.isBlank()) continue; // 跳过空行 String[] fields = line.split(";"); String name = fields[0]; String score = fields[1]; Customer customer = new Customer(name, score); customerList.add(customer); } scan.close(); } // 增加customerList的getter方法,方便测试时获取结果校验 public List<Customer> getCustomerList() { return customerList; }
注意:测试前请确保
Customer类已重写equals()和hashCode()方法,否则对象属性比对会失败。
2.2 准备测试资源
在项目的src/test/resources目录下创建测试专用的输入文件,比如:
- 正常场景测试文件
test_customer_normal.txt,内容如下:
John Smith;45; Adam West;78;
- 边界场景测试文件
test_customer_empty.txt:空文件,测试空输入场景 - 异常场景测试文件
test_customer_invalid.txt:包含格式错误的行,测试异常处理逻辑
2.3 编写JUnit 5测试代码
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import java.io.File; import java.io.FileNotFoundException; import java.util.List; class CustomerFileScannerTest { @Test void testScanLocalFile_NormalCase() throws FileNotFoundException { // 1. 读取测试资源目录下的测试文件 ClassLoader classLoader = getClass().getClassLoader(); File testFile = new File(classLoader.getResource("test_customer_normal.txt").getFile()); // 2. 调用业务方法 YourServiceClass service = new YourServiceClass(); // 替换为你实际的业务类名 service.scanLocalFile(testFile); // 3. 校验结果 List<Customer> result = service.getCustomerList(); assertEquals(2, result.size()); assertEquals("John Smith", result.get(0).getName()); assertEquals("45", result.get(0).getScore()); assertEquals("Adam West", result.get(1).getName()); assertEquals("78", result.get(1).getScore()); } @Test void testScanLocalFile_EmptyFile() throws FileNotFoundException { ClassLoader classLoader = getClass().getClassLoader(); File testFile = new File(classLoader.getResource("test_customer_empty.txt").getFile()); YourServiceClass service = new YourServiceClass(); service.scanLocalFile(testFile); assertTrue(service.getCustomerList().isEmpty()); } }
内容的提问来源于stack exchange,提问作者dennis
相关产品推荐
相关产品推荐

