JUnit
JUnit
依赖
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
确保main文件和test文件结构一致
基础语法
// Main
package pk;
public class Main {
public static int preSum(int n){
int res=0;
for(int i=1;i<=n;i++){
res+=i;
}
return res;
}
public int preTime(int n){
int res=1;
for(int i=1;i<=n;i++){
res*=i;
}
return res;
}
}
// Test
package pk;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class TestPreSum {
@Test
void testPreSum() {
int res1 = Main.preSum(3); // 调用静态方法
assertEquals(6, res1); // 期望值在前,实际值在后
Main main=new Main();
int res2=main.preTime(3); // 实例方法
assertEquals(6,res2);
}
}
常用方法
assertTrue(): 期待结果为trueassertFalse(): 期待结果为falseassertNotNull(): 期待结果为非nullassertArrayEquals(): 期待结果为数组并与期望数组每个元素的值均相等-
使用浮点数时,由于浮点数无法精确地进行比较,因此,我们需要调用
assertEquals(double expected, double actual, double delta)这个重载方法,指定一个误差值:java assertEquals(0.1, Math.abs(1 - 9 / 10.0), 0.0000001);
使用@BeforeEach和@AfterEach
如果测试对象需要初始化,或者测试完需要清理,可以用@BeforeEach和@AfterEach,@BeforeAll和@AfterAll避免每个测试方法都编写初始化语句
// Main
public class Calculator {
private long n = 0;
public long add(long x) {
n = n + x;
return n;
}
public long sub(long x) {
n = n - x;
return n;
}
}
// Test
public class CalculatorTest {
Calculator calculator;
@BeforeEach
public void setUp() {
this.calculator = new Calculator();
}
@AfterEach
public void tearDown() {
this.calculator = null;
}
@Test
void testAdd() {
assertEquals(100, this.calculator.add(100));
assertEquals(150, this.calculator.add(50));
assertEquals(130, this.calculator.add(-20));
}
@Test
void testSub() {
assertEquals(-100, this.calculator.sub(100));
assertEquals(-150, this.calculator.sub(50));
assertEquals(-130, this.calculator.sub(-20));
}
}
- 实例变量在
@BeforeEach中初始化,在@AfterEach中清理,它们在各个@Test方法中互不影响,因为是不同的实例; - 静态变量在
@BeforeAll中初始化,在@AfterAll中清理,它们在各个@Test方法中均是唯一实例,会影响各个@Test方法。 - 大多数情况下,使用
@BeforeEach和@AfterEach
异常测试
JUnit提供assertThrows()来期望捕获一个指定的异常
// Main
public class Calculator {
public static int divide(int a, int b) {
if (b == 0) throw new IllegalArgumentException("除数不能为0");
if (a < 0 || b < 0) throw new NegativeNumberException("不支持负数");
return a / b;
}
}
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
@Test
void testDivideByZero() {
assertThrows(
IllegalArgumentException.class, // 第一个参数,期望捕获的异常类
() -> Calculator.divide(10, 0) // 第二个参数.函数式编程,待测试的方法
);
}
// 不同的异常写不同的测试
@Test
void testDivideWithNegative() {
assertThrows(NegativeNumberException.class,
() -> Calculator.divide(-5, 2));
}
参数化测试
依赖
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
用 @ParameterizedTest 替代 @Test,再配合一个参数源注解提供测试数据
参数源常用@MethodSource和CsvFileSource
-
使用
@MethodSource```java // Main package pk;
public class Main { public static int preSum(int n){ int res=0; for(int i=1;i<=n;i++){ res+=i; } return res; } } ```
@MethodSource传入提供数据的方法名(String)```java // test package pk;
import ...
public class TestPreSum {
@ParameterizedTest @MethodSource("preSumDataProvider") // 方法名 void testPreSum(int n,int expected) { // 形参传入测试所需参数和预期值 assertEquals(expected,Main.preSum(n)); } // 静态返回Stream<Arguments> static Stream<Arguments> preSumDataProvider(){ return Stream.of( // 使用工厂方法 // 传入所需参数和预期结果 Arguments.of(0,0), Arguments.of(1,1), Arguments.of(2,3), Arguments.of(3,6) ); }} ```
-
使用
@CsvFileSource假设在
src/test/resources/test-data.csv文件中写入测试数据:java n,expected 0,0 1,1 2,3 3,6 5,15@CsvFileSource传入resources = "/test-data.csv"路径规则和classpath读取资源一致numLinesToSkip = 1(需要跳过的首行数)- 默认用逗号分隔,可以用
delimiterString = "|"指定其他分隔符
编写测试方法:
```java package pk;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvFileSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CalculatorTest {
@ParameterizedTest @CsvFileSource(resources = "/test-data.csv", numLinesToSkip = 1) void testSumWithCsvFile(int n, int expected) { assertEquals(expected, Calculator.sum(n)); }} ```
评论