Java单元测试框架JUnit的基本使用

Java单元测试框架JUnit的基本使用

单元测试十分重要!尤其是微服务web之类的复杂项目,这类项目代码的嵌套层次多,方法层数多,如果不做单元测试,功能完成之后bug的数量级肯定会很大。如果你有非常严格的单元测试,每写一个方法,每完成一模块或者功能,都进行了单元测试,那么在业务功能整体完成之后,你就会发现你基本不可能出现bug。单元测试的好处非常多,还可以极大的减少程序后期的维护成本和工作量。有了成套的单元测试,后期改代码排查问题,你就不用一遍一遍的读代码了,直接跑一遍单元测试就知道大概了。

1. 安装使用

maven配置,简单而俗套

 <!-- https://mvnrepository.com/artifact/junit/junit -->
 <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.13</version>
   <scope>test</scope>
 </dependency>
2. 实例待测试代码

一个别人写好的计算类,做实例用的,参考价值还可以,拿来直接用。

public class Calculator {
    public int calculate(String expression) {
        String[] ss = expression.split("\\+");
        System.out.println(expression + " => " + Arrays.toString(ss));
        int sum = 0;
        for (String s: ss) {
            sum += Integer.parseInt(s.trim());
        }
        return sum;
    }
}
3. 编写测试类

大体的结构基本在创建项目的时候,Maven原型已经给你创建好了,具体的细节目录和包结构因人而异,可以随意发挥。

import org.junit.Test;
import static org.junit.Assert.*;

public class CalculatorTest {
    @Test
    public void calculate() {
        assertEquals(4, new Calculator().calculate("1 + 2"));
        assertEquals(6, new Calculator().calculate("1 + 2 + 3"));
    }
}
4. 常用的断言方法
  • assertEquals(100, x): 断言相等
  • assertArrayEquals({1, 2, 3}, x): 断言数组相等
  • assertEquals(3.1416, x, 0.0001): 浮点数组断言相等
  • assertNull(x): 断言为null
  • assertTrue(x > 0): 断言为true
  • assertFalse(x < 0): 断言为false;
  • assertNotEquals: 断言不相等
  • assertNotNull: 断言不为null
5. 单元测试逻辑结构
  1. 在@Before方法中初始化测试资源
  2. 在@After方法中释放测试资源
  3. @BeforeClass: 初始化非常耗时的资源, 例如创建数据库
  4. @AfterClass: 清理@BeforeClass创建的资源, 例如创建数据库
  5. 对于每一个@Test方法的执行顺序
  • 单个@Test方法执行前会创建新的XxxTest实例, 实例变量的状态不会传递给下一个@Test方法,
  • 单个@Test方法执行前后会执行@Before和@After方法
  1. 执行顺序
  • 执行类的构造函数=>执行@Before方法=>执行@Test方法=>执行@After方法
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class SequenceTest {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        System.out.println("BeforeClass()");
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        System.out.println("AfterClass()");
    }

    @Before
    public void setUp() throws Exception {
        System.out.println("    Before()");
    }

    @After
    public void tearDown() throws Exception {
        System.out.println("    After()");
    }

    public SequenceTest() {
        System.out.println("  new SequenceTest()");
    }

    @Test
    public void testA() {
        System.out.println("    testA()");
    }

    @Test
    public void testB() {
        System.out.println("    testB()");
    }

}
6. 参数化测试

@RunWith: 当类被@RunWith注释修饰, 或者类继承了一个被该注解类修饰的类, JUnit将会使用这个注解所指明的运行器(runner)来运行测试, 而不是JUni默认的运行器
要进行参数化测试,需要在类上面指定如下的运行器:@RunWith (Parameterized.class)
然后,在提供数据的方法上加上一个@Parameters注解,这个方法必须是静态static的,并且返回一个集合Collection。
具体详细说明如下:

  1. 测试类必须由Parameterized测试运行器修饰
  2. 准备数据。数据的准备需要在一个方法中进行,该方法需要满足一定的要求:
  • 该方法必须由Parameters注解修饰
  • 该方法必须为public static的
  • 该方法必须返回Collection类型
  • 该方法的名字不做要求
  • 该方法没有参数
@RunWith(Parameterized.class)
public class TestParams {

    @Parameterized.Parameters
    public static Collection<?> data() {
        return Arrays.asList(new Object[][] { { "1+2", 3 }, { "1+2+3", 8 }, { "123+456", 579 }, { " 1 + 5 + 10 ", 16 } });
    }

    Calculator calc;

    @Parameterized.Parameter(0)
    public String input;

    @Parameterized.Parameter(1)
    public int expected;

    @Before
    public void setUp() {
        calc = new Calculator();
    }

    @Test
    public void testCalculate() {
        int r = calc.calculate(this.input);
        assertEquals(this.expected, r);
    }

}
7. 其他常用测试
7.1 异常测试

异常测试可以通过@Test(expected=Exception.class), 对可能发生的每种类型的异常进行测试

  • 如果抛出了指定类型的异常, 测试成功
  • 如果没有抛出指定类型的异常, 或者抛出的异常类型不对, 测试失败
// 发生了ArithmeticException异常, 代码通过
@Test(expected = ArithmeticException.class)
    public void testException() {
       int i = 1 / 0;
    }
7.1 超时设置

在测试类的方法上使用 @Timeout 注解,测试类的所有方法应用 Timeout 规则
@Test(timeout=1000)可以设置超时时间,单位是毫秒
@Timeout 注解来测试任意特定方法的执行时间。如果测试方法的执行时间大于指定的超时参数,测试方法将抛出异常,测试结果为失败。指定的超时参数是以毫秒记。

mport org.junit.*;

public class TimeOutTest {

	@Test(timeout = 1000)  
	public void infinity() {  
		while (true);  
	}   
}
8. 参考教程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值