Vintage: Another set of APIs, which runs older junit tests.
How to write JUnit test
Create an instance of the class under test
Set up inputs
Execute the code you want to test
Verify the result is what you expect
Test life cycle
JUnit 5 provides many lifecycle hooks, and you can use them by adding annotations:
1 2 3 4
@BeforeAll @BeforeEach @AfterAll @AfterEach
Note: Methods with annotation @BeforeAll and @AfterAll must be static so that they do not need to rely on any instance.
JUnit test demo
1. Build Maven project
Basically, if you want to build a project using Maven, you should add two dependencies in pom.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
<dependencies> <!-- junit-jupiter-engine: Implementation of the TestEngine API for JUnit Jupiter.--> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.5.2</version> <scope>test</scope> </dependency>
<!-- junit-jupiter-api: API for writing tests using JUnit Jupiter.--> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.5.2</version> <scope>test</scope> </dependency> </dependencies>
You should also add maven-compiler-plugin to specify your JDK version(in this case we use JDK 11):
// To enable JUnit Jupiter execute all test methods on the same test instance(in this case, instance of MathUtilsTest). // The default mode of @TestInstance is PER_METHOD, which means that JUnit would create an instance of MathUtilsTest for each method. @TestInstance(TestInstance.Lifecycle.PER_CLASS) classMathUtilsTest{
// We should declare mathUtils outside all methods so that each method can share it. MathUtils mathUtils;
@BeforeAll // Methods with annotation @BeforeAll and @AfterAll must be static so that they do not need to rely on any instance. staticvoidbeforeAllInit(){ System.out.println("This needs to run before all."); }
@BeforeEach voidinit(){ mathUtils = new MathUtils(); }
// @Test: Informs the JUnit engine what methods need to run. @Test voidtestAdd(){ int expected = 2; int actual = mathUtils.add(1, 1); assertEquals(expected, actual); }
@Test @Disabled// Skip this test. voidtestDivide(){ assertThrows(ArithmeticException.class, () -> mathUtils.divide(1, 0), "Divide by zero should throw."); }
@Test voidtestMultiply(){ // use lambda in assertAll assertAll( () -> assertEquals(4, mathUtils.multiply(2, 2), "Should return the right product."), () -> assertEquals(0, mathUtils.multiply(0, 2)), () -> assertEquals(-2, mathUtils.multiply(2, -1)) ); }
@Test @DisplayName("Testing computeCircleArea.") voidtestComputeCircleArea(){ assertEquals(314.1592653589793, mathUtils.computeCircleArea(10), "Should return right circle area."); }
@Nested classAddTest{ @Test voidtestAddPositive(){ int expected = 2; int actual = mathUtils.add(1, 1); // lambda: messageSupplier assertEquals(expected, actual, () -> "Should return " + expected + ", but return " + actual); }
Unit tests can only show the presence of errors; it cannot show the absence of errors. In another word, tests can only test the cases that you can think of, but they cannot test the cases that you cannot imagine.