为你的 Main.java 添加 JUnit 单元测试

前言

在同学们做 OO(pre) 作业的时候,肯定常常遇到需要给自己的 Main.java 文件添加单元测试以满足覆盖率要求的情况。或者,当你拥有一组的测试数据时,你可能会需要添加单元测试,自动化评测你的代码以检验正确性。但是,我们的 Main.java 又常常使用 scan(System.in) 作为输入,这个输入方式会要求从控制台读入数据,如果不对它下手,我们就只能每次都复制粘贴数据来测试代码;如果直接对它下手,又无法通过课程组的测试。因此,我们的解决方法是照常从控制台读入数据,但是在 JUnit 文件中对 System.in 重定向以实现自动化测试。

具体实现

我们使用一个 String 来保存我们的输入数据,然后重定向系统的输入流(即 System.in)为该字符串,最后调用 Main 类中的 main 方法(入口方法)即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.PrintStream;

import org.junit.Test;

import src.MainClass;

public class MainClassTest {
final InputStream originalIn = System.in;
final PrintStream originalOut = System.out;

@Test
public void testMain() throws FileNotFoundException
{
String s = "2\n" +
"1 123456 advName\n" +
"2 123456 123 bottleName 40";
System.out.println(s);
System.setIn(new ByteArrayInputStream(s.getBytes()));
MainClass test = new MainClass();
MainClass.main(null);
}
}

说明

Q: 为什么不使用文件输入流呢? A: 显然,我们不知道数据文件在评测机中的绝对路径。考虑相对路径,Java 代码本身是在虚拟机 jvm 中运行的,因此文件的相对路径取决于文件的执行路径,但是我们也不知道文件的执行路径,因此我们只能使用字符串数据流来输入数据。 Q: 我们能不能在本地输出到文件中呢? A: 答案是可以的。具体代码如下。

1
2
3
4
5
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
PrintStream prt_path = new PrintStream("src\\test\\java\\test\\MainClassInput.out");
System.setOut(prt_path);

Q: 数据量太大了,我不想一行行手敲? A: 一方面,你可以考虑使用文件输入流(这仅在你的本地可行,而且需要考虑相对位置,不推荐),具体代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

import org.junit.Test;

import src.MainClass;

public class MainClassTest {
@Test
public void test() throws FileNotFoundException
{
FileInputStream in = new FileInputStream("src\\test\\java\\test\\MainClassInput.in");
PrintStream prt = new PrintStream("src\\test\\java\\test\\MainClassInput.out");
System.setIn(in);
System.setOut(prt);
MainClass.main(null);
}
}

另一方面,你可以尝试使用我编写的自动生成工具,仅需要指定一般文本形式的测试数据文件即可自动生成 Test.java,简单便捷。 工具下载链接: https://bhpan.buaa.edu.cn/link/AAB0154647C16D456BB3B8365E3B521070 Github 项目地址:https://github.com/AOSTL/MainclassTestGenerator/ 下载后,请重命名为 mtg.exe 请在命令行中使用。 喜欢的话点个 Star 吧!