编写Junit测试

添加JUnit 框架

Eclipse中 Project ->Properties -> Java Build Path ->Libraries ,添加JUnit 5 库。

test目录下新建包路径后,添加 methodTest文件,文件中测试写法

@Test
void testMethod(){
    assertEquals(result ,Class.method(input));
}
  • assertTrue():期待结果为true
  • assertFalse():期待结果为false
  • assertNotNull():期待结果为非null
  • assertArrayEquals():期待结果为数组并与期望数组每个元素的值均相等

使用浮点数时,由于浮点数无法精确地进行比较,因此,我们需要调用 assertEquals(double expected, double actual, double delta)这个重载方法,指定一个误差值。

异常测试

捕获异常

@Test
void testNegative(){
    assertThrows(IllegalArgumentException.class, new Executable(){
        @Override
        public void execute() throws Throwsable {
            Class.method(-1);
        }
    }
}

可以简写为

@Test
void testNegative(){
    assertThrows(IllegalArgumentException.class, () -> {
        Class.method(-1);
    });
}

使用Fixture

JUnit 提供了编写测试前准备、测试后清理的固定代码,我们称之为Fixture。

测试的时候,我们要先初始化对象,我们不必在每个测试方法中都写上初始化代码,而是通过@BeforeEach来初始化,通过@AfterEach来清理资源。

public class calculatorTest {
    Calculator calculator;

    @BeforeEach
    public void setUp(){
        this.calculator = new Calculator();
    }

    @AfterEach
    public void tearDown() {
        this.calculator = null;
    }


    @Test
    void testSub(){
        assertEquals(-2,this.calculator.sub(2));
    }


}

CalculatorTest测试中,有两个标记为@BeforeEach@AfterEach的方法,它们会在运行每个**@Test**方法前后自动运行。
还有一些资源初始化和清理可能更加繁琐,而且会耗费较长的时间,例如,初始化数据库。JUnit还提供了@BeforeAll@AfterAll,它们在运行所有@Test前后运行,顺序如下

invokeBeforeAll(CalculatorTest.class);
for(Method testMethod: findTestMethods(CalculatorTest.class)) {
  var test = new CalculatorTest();
    invokeBeforeEach(test);
    invokeTestMethod(test,testMethod);
    invokeAfterEach(test);
}
invokeAfterAll(CalculatorTest.class);

因为@BeforeAll@AfterAll在所有@Test方法运行前后仅运行一次,因此,它们只能初始化静态变量。

条件测试

条件测试是根据某些注解在运行期让JUnit 自动忽略某些测试

  • 条件测试一般以Enabled… 或 Disabled…开头
  • @EnabledOnOs(OS.WINDOWS) ——仅当程序运行在Windows系统上时执行测试
  • @EnabledOnOs({OS.LINUX, OS.MAC})——仅当程序运行在linux系统或MAC系统上时执行测试
  • @DisabledOnOs(OS.WINDOWS)——仅当程序运行在非Windows系统上时执行测试
  • @DisabledOnJre(JRE.JAVA_8) ——只能在Java 9或更高版本执行测试
  • @EnbledIfSystemProperty(named = "os.arch", matches = ".*64.*")——只能在64位操作系统上执行测试
  • @EnabledIfEnvironmentVariable ——传入环境变量DEBUG=true才能执行的测试

    参数化测试

    参数化测试的注解是@ParameterizedTest,而不是普通的@Test

    @ParameterizedTest
    @ValueSource(ints = {-1, -5, -100})
    void testAbsNegative(int x ) {
      assertEquals(-x , Math.abs(x));
    }
    

    要用参数化测试的方法来测试,我们不但要给出输入,还要给出预期输出。因此,测试方法至少需要接收两个参数。
    例如我们编写一个StringUtils.capitalize()方法,它会把字符串的第一个字母变为大写,后续字母变为小写: ```java public class StringUtils {

    public static capitalize(String s) {

      if(s.lenght() == 0 )  return s.toUpperCase(); 
      return Character.toUpperCase(s.charAt(0)) + s.substring(1).toLowerCase();
    

    } }

参数如何传入?<br />一、<br />**最简单的方法是通过**`**@MethodSource**`**注解,它允许我们编写一个同名的静态方法来提供测试参数**
```java
@ParameterizedTest
@MethodSource
void testCapitalize(String input, String result) {
    assertEquals(result, StringUtils.capitalize(input));
}


static List<Arguments> testCapitalize() {
  List<Arguments> argumentsList = new ArrayList<>();
    argumentsList.add(Arguments.arguments("abc","Abc"));
    argumentsList.add(Arguments.arguments("APPLE","Apple"));
    return argumentsList;
}

:::info 如果静态方法和测试方法的名称不同,@MethoedSource也允许指定方法名。但使用默认同名方法最方便。 ::: 二、

@ParameterizedTest
@CsvSource({"abc, Abc","APPLE, Apple","gooD,Good"})
void testCapitalize(String input ,String result){
    assertEquals(result,StringUtils.capitalize(input));
}

三、

@ParameterizedTest
@CsvFileSource(resource = {"/test-capitalize.csv"})
void testCapitalize(String input, String result){
    assertEquals(result,StringUtils.capitalize(input));
}

JUnit 只在classpath中查找指定的CSV文件,因此,test-capitalize.csv这个文件要放到test目录下,内容如下

app, Apple
HELLO, Hello
Junit, Junit
ReSource, Resource