前面一篇文章,我们介绍了Java中单元测试(Junit)的作用、使用以及需要注意的事项。
这一篇我们带来2个案例
第一个案例:
1、使用断言:查看自己方法运行结果,跟预期的值是否一致。
2、这很重要,这里也是底层原理是采用了异常抛出的机制,如果预期的值不一样,会抛出一个异常进行提示。
3、看到这里你肯定想,这有什么好处?,确实如果只是一个测试或者两三个用例(一个测试方法),确实作用不大,我们可以直接测试,但是如果我们的测试用例非常的多几十个几百个测试用例,你是否测试的过来呢,是否有那么多的精力呢,去一个个在控制台或者其他什么地方查看结果呢?
让我们带着疑问来开始学习吧,首先我会把下面这段代码摆在这里,应该是蛮好理解的。
代码意图:希望被测试的方法能够对输出结果进行正确的结果进行判断,我们这里希望a/b;(5/2)的结果能够不进行取证得到2.5,如果
不是2.5就抛出异常,下面这段代码用了断言。
package com.ligong.test;
import junit.framework.TestCase;
import org.junit.Test;
public class TestCaseDemo {
@Test
public void TestCalcDivide(){
double result = Calc.divide(5, 2);
System.out.println("a/b="+result);
TestCase.assertEquals(2.5,result);
}
}
class Calc{
/* 这个方法是a除以b返回其结果,
为了在测试类中直接可以通过来类名进行调用,
所以这里我写为static*/
public static double divide(int a,int b){
return a/b;
}
}
下面带来第二个案例,应用场景也是非常广的。
- 测试方法的时候, 我们希望逻辑不要污染源数据 (不要发生改变)
- 需求 : 现有文件 user.txt 内部存储了很多用户名, 需要将用户名前面都加入序号。
- 断言 : 源文件长度, 修改后的长度, 是否相同
在学习这个案例之前,我们需要引入以下知识。
这里我们引入了@Before 和@After ,其主要作用是在被用来在被@Test注解所标记方法 之前执行和之后执行。下面是这2个注解的效果演示
package com.ligong.test;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class BeforeAfterDemo {
@Test
public void show1(){
System.out.println("show1");
}
@After
public void show2(){
System.out.println("show2");
}
@Before
public void show3(){
System.out.println("show3");
}
}
运行结果展示:
第二案例全部代码展示:
package com.ligong.test;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.*;
import java.util.ArrayList;
public class JunitTest2 {
/*
* 在@Test所标记方法执行之前执行
* */
@Before
public void init() throws Exception {
System.out.println("文件备份....");
//当前项目下user.txt文件,不是模块下,因为默认下的路径就是项目根目录
File src = new File("user.txt");
//为了不影响user.txt文件,所以需要把源文件进行拷贝
File copyFile = new File("userCopy.txt");
//读取创建一个字节读流,关联user.txt文件
FileInputStream fis = new FileInputStream(src);
//关联userCopy.txt文件,
FileOutputStream fos = new FileOutputStream(copyFile);
int len;
//声明一个字节数组,为了提高读写效率
byte[] bys = new byte[8192];
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
}
fis.close();
fos.close();
}
//对user.txt文件每行添加序号
@Test
public void updateUserInfo() throws Exception {
File file = new File("user.txt");
//记录源文件的长度
long beforeLength = file.length();
//声明一个字符缓冲流,目的是可以进行一行一行的读取
BufferedReader br = new BufferedReader(new FileReader(file));
//为了把数据按行进行存储,所以声明一个集合进行有序的存储
ArrayList<String> list = new ArrayList<>();
String line;
while ((line = br.readLine()) != null) {
list.add(line);
}
br.close();
int lineNumber = 1;
//声明一个字符写缓冲流
BufferedWriter bw = new BufferedWriter(new FileWriter("user.txt"));
for (String s : list) {//每遍历一次,向user.txt文件写入一行
bw.write(lineNumber + "." + s);//每写入一行,在该行开头添(加序号.),例如1.
bw.newLine();//写完一行后进行换行,newLine具有跨平台效果
bw.flush();//把缓冲区的字符刷入,字节流则不用
lineNumber++;//操作完毕后,把序号进行自增
}
bw.close();
//记录添加序号后的文件长度
long afterLength = file.length();
//进行断言判断
TestCase.assertEquals(beforeLength, afterLength);
}
//执行完操作后恢复被操作的文件user.txt。
@After
public void close() throws Exception {
File src = new File("userCopy.txt");
File copyFile = new File("user.txt");
//还原user.txt文件中的内容
copyFile.createNewFile();
FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(copyFile);
int len;
byte[] bys = new byte[8192];
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
}
fis.close();
fos.close();
src.delete();
System.out.println("文件还原....");
}
}
运行结果:
下面我来一起看看力扣网站上,在单元测试上的应用。