基于JUnit4的使用
一、基本使用
1.创建实体类
package learning.bean;
import lombok.*;
@Data
@NoArgsConstructor
@AllArgsConstructor//添加此注解,自动生成所有属性对应的有参构造方法
public class Goods {
private String name;//商品名称
private int count;//商品数量
//业务方法
public Goods mergeGoods(Goods other){
if(!sameGoodsType(other)){
return null;
}
this.count += other.count;
return this;
}
//认为名字和数量一样才是同一个货物
@Override
public boolean equals(Object o) {
Goods other = (Goods) o;
if(this.name.equals(other.name) && this.count == other.count){
return true;
}
return false;
}
//假定名字一样即类型一样
public boolean sameGoodsType(Goods other){
return this.name.equals(other.name);
}
}
2.测试方法
import learning.bean.Goods;
import org.junit.*;
import org.junit.experimental.categories.Category;
public class TestGoods {
private Goods g1;
private Goods g2;
//@BeforeClass要求必须是静态方法
@BeforeClass
public static void classInit(){
System.out.println("测试类加载时,初始化调用的方法!");
}
@AfterClass
public static void classDestroy(){
System.out.println("测试类销毁时,调用的方法!");
}
@Before
public void init(){
System.out.println("测试对象初始化时,调用的方法!");
g1 = new Goods("手机",2);
g2 = new Goods("手机",3);
}
@After
public void destroy(){
System.out.println("测试对象销毁时,使用的方法!");
}
@Category(RequiredTest.class) //标记当前测试方法的种类(比如:发行版本的测试类、debug版本的测试类)
@Test
public void testSameType(){
// System.out.println(g1.sameGoodsType(g2));
Assert.assertTrue(g1.sameGoodsType(g2));
//assert断言:assertTrue认定返回true,如果认定失败,则测试不通过
}
@Test//测试是否通过,以及测试时间
//@Ignore//忽略该测试
public void testMerge(){
Goods gm = new Goods("手机",5);//测试之前创建的两个新对象数量之和是否为此对象
Assert.assertEquals(gm, g1.mergeGoods(g2));
}
}
3.测试结果
二、进阶使用
1.创建实体类
package learning.bussiness;
//异常接口
public class StoreFullException extends Exception{
public StoreFullException(String message){
super(message);
}
}
package learning.bussiness;
import learning.bean.Goods;
import java.util.LinkedList;
import java.util.List;
//仓库类,进行简单业务
public class Store {
private static final int MAX_COUNT = 10;
private List<Goods> allGoods = new LinkedList<Goods>();
//增加货物
public void addOneGoods(Goods g) throws StoreFullException{
if(allGoods.size() >= MAX_COUNT){
throw new StoreFullException("库存已满,不能入库!库存最大容量为:"+MAX_COUNT);
//return; throw相当于终止异常,return永远无法达到,会报unreachable code错误
}
allGoods.add(g);
}
//通过名字查找货物
public Goods getGoodsByName(String goodsName){
if(allGoods.isEmpty()){
return null;
}
for(Goods g: allGoods){
if(g.getName().equals(goodsName)){
return g;
}
}
return null;
}
//显示所有货物
public void showAllGoods(){
for(Goods g: allGoods){
System.out.println(g);
}
}
}
2.测试方法
import learning.bean.Goods;
import learning.bussiness.Store;
import learning.bussiness.StoreFullException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class TestStore {
private Store store;
@Before
public void init(){
store = new Store();
Goods g = new Goods();
g.setName("手机");
g.setCount((int)Math.random()*51 + 50);
try {
store.addOneGoods(g);
} catch (StoreFullException e) {
e.printStackTrace();
}
}
@Test(expected = StoreFullException.class) //期望报StoreFullException.class异常,报的话测试即通过,不报测试不通过
public void testAddTooMuchGoods() throws StoreFullException {
for(int i = 1; i <= 20; i++){
Goods g = new Goods("货物" + i, (int)Math.random()*51+50);
store.addOneGoods(g);
}
}
@Test
public void testGetGoodsByName(){
Goods g = store.getGoodsByName("手机");
Assert.assertNotNull("测试失败,货物未找到" , g);
}
@Test(timeout = 100) //执行在100ms内即认为测试通过
public void testTimeout() throws InterruptedException {
// try {
Thread.sleep(200);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
3.测试结果
三、使用参数列表进行多次测试
1.测试方法
import learning.bean.Goods;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.util.ArrayList;
import java.util.List;
@RunWith(Parameterized.class) //运行时,使用多参数化的方式;下面的类在运行时,有参数列表化的功能
public class TestSameGoodsWithParameters {
//1.测试的参数,需以属性的方式存在于类中
private Goods firstGoods;
private Goods secondGoods;
//2.必须提供同样个数参数的构造方法,测试时,每次取两个商品填入构造方法
public TestSameGoodsWithParameters(Goods firstGoods, Goods secondGoods){
this.firstGoods = firstGoods;
this.secondGoods = secondGoods;
}
//3.必须有@Parameters,加在一个静态方法之前,此方法用于提供所有测试所需的参数信息
//此方法官方要求形式为:public static Iterable<Object[]> xxx()
@Parameters
public static List<Goods[]> getParams(){
//以下list中的一个元素为一次测试所需要的所有数据
List<Goods[]> gList= new ArrayList<Goods[]>();
gList.add(new Goods[]{new Goods("手机",1),new Goods("手机",1)});
gList.add(new Goods[]{new Goods("手机",2),new Goods("手机",2)});
gList.add(new Goods[]{new Goods("手 机",3),new Goods("手 机",3)});
gList.add(new Goods[]{new Goods("手+机",2),new Goods("手+机",1)});
gList.add(new Goods[]{new Goods("电冰箱",1),new Goods("电冰箱",1)});
gList.add(new Goods[]{new Goods("手_机",1),new Goods("手_机",1)});
return gList;
}
@Test
public void testSameGoods(){
System.out.println(this);//new六次对象,测试六次
Assert.assertEquals(firstGoods, secondGoods);//自己重写的equals方法中,认为名字和数量一致时,即为true
}
}
2.测试结果
四、测试套件,同时测试多个其他测试类
1.测试方法
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
//测试套件
@RunWith(Suite.class)
@SuiteClasses({TestGoods.class,TestSameGoodsWithParameters.class,TestStore.class})
public class TestAll {
//统一测试类,本身没有测试方法
}
2.测试结果
五、分类测试
1.测试方法
//实际生产中有多个service层,不同service层中方法多个,方法也分为一级,二级,三级,此测试为
//测试不同service层中的同级方法
//该接口相当于一个标记,用了此标记的认为要进行该测试,使用@Categroy标记
public interface RequiredTest {
}
import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.IncludeCategory;
import org.junit.experimental.categories.Categories.ExcludeCategory;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
//按分类的方式测试
@RunWith(Categories.class)
@IncludeCategory({RequiredTest.class}) //要测试的哪些类
//@ExcludeCategory(...) //测试没有标记的,与上面的不可同时存在
@SuiteClasses({TestGoods.class,TestStore.class}) //扫描所有包含的类,测试前面加@Category的方法
//多参数在此无法扫描运行
public class TestCategory {
}
2.测试结果