JUnit断言
JUnit断言允许我们编写有效的测试方法。
JUnit 5是最新版本,JUnit Jupiter提供了许多断言来断言不同类型的语句。
JUnit断言
JUnit Jupiter org.junit.jupiter.api.Assertions类提供了在我们的测试代码中使用的实用程序方法的集合。
所有这些方法都是静态的,因此我们可以导入它们并编写流畅的代码。
几乎所有这些方法都被重载以支持原语,对象,集合,流,数组等。
import static org.junit.jupiter.api.Assertions.*;
让我们通过示例来看一些重要的JUnit assert方法。
fail()
这用于使测试失败,这在测试方法仍在进行中并且希望通过快速失败测试来表明这一点时很有用。
有很多重载的fail()方法,让我们看一些。
@Test @DisplayName("This will Fail, don't worry!") void test_fail() { fail(); fail("Not yet implemented"); fail(() -> { return "Not yet implemented"; }); fail("Not Yet Implemented", new RuntimeException("Explicitly Failed")); fail(new RuntimeException("Explicitly Failed")); }
我们可以提供自定义失败消息并指定失败原因。
assertNull()和assertNotNull()
这些方法用于检查指定的对象是否为null。
我们还可以指定自定义失败消息。
@Test @DisplayName("assertNull Examples") void test_assertNull() { assertNull(null); //assertNull(new Object(), "assertNull Fail Message"); } @Test @DisplayName("assertNotNull Examples") void test_assertNotNull() { assertNotNull(new Object()); //assertNotNull(null, "assertNotNull Fail Message"); }
assertSame()和assertNotSame()
这些方法用于断言预期元素和实际元素是否相同。
JUnit对这些方法使用==运算符来检查它们是否引用了同一对象。
@Test @DisplayName("assertSame Examples") void test_assertSame() { assertSame("Hi", "Hi"); //this will fail //assertSame("Hi", new String("Hi"), "My Failure Message"); } @Test @DisplayName("assertNotSame Examples") void test_assertNotSame() { assertNotSame("Hi", "Hello"); //this will fail //assertNotSame("Hi", "Hi", "assertNotSame Failure Message"); }
assertTrue()和assertFalse()
声明提供的条件为"真"或者"假"。
@Test @DisplayName("assertTrue Examples") void test_assertTrue() { assertTrue(3 > 0); assertTrue(() -> { return true; }); assertTrue(3 > 0, "assertTrue fail message"); assertTrue(3 > 0, () -> { return "assertTrue fail message"; }); assertTrue(() -> { return true; }, "assertTrue fail message"); assertTrue(() -> { return true; }, () -> { return "assertTrue fail message"; }); } @Test @DisplayName("assertFalse Examples") void test_assertFalse() { assertFalse(3 < 0); assertFalse(() -> { return false; }); assertFalse(3 < 0, "assertFalse fail message"); assertFalse(3 < 0, () -> { return "assertFalse fail message"; }); assertFalse(() -> { return false; }, "assertFalse fail message"); assertFalse(() -> { return false; }, () -> { return "assertFalse fail message"; }); }
assertEquals()和assertNotEquals()
这两种方法用于断言预期对象和实际对象是否相等。
他们使用对象的equals()方法检查相等性。
@Test @DisplayName("assertEquals Examples") void test_assertEquals() { assertEquals(10, 10); assertEquals(true, true, "assertEquals Failure Message"); assertEquals("Hi", new String("Hi")); assertEquals(new File("test"), new File("test")); } @Test @DisplayName("assertNotEquals Examples") void test_assertNotEquals() { assertNotEquals(10, 100); assertNotEquals(true, false, "assertEquals Failure Message"); assertNotEquals("Hi", new String("Hello")); assertNotEquals(new File("test"), new File("test1")); }
assertArrayEquals()
断言期望数组和实际数组完全相等。
数组元素按索引匹配。
@Test @DisplayName("assertArrayEquals Examples") void test_assertArrayEquals() { String[] s1 = { "A", "B" }; String[] s2 = { "A", "B" }; assertArrayEquals(s1, s2); assertArrayEquals(s1, s2, "My Custom Failure Message"); }
assertIterableEquals()
此方法用于可迭代对象检查它们是否相等。
请注意,基础实现可以不同。
元素通过索引匹配以相等。
@Test @DisplayName("assertIterableEquals Examples") void test_assertIterableEquals() { List<String> l1 = new ArrayList<>(Arrays.asList("A", "B")); List<String> l2 = new LinkedList<>(Arrays.asList("A", "B")); assertIterableEquals(l1, l2); assertIterableEquals(l1, l2, "Custom Failure Message"); }
assertThrows()
断言所提供的可执行文件的执行将引发ExpectedType的异常并返回该异常。
如果没有引发异常,或者引发了其他类型的异常,则此方法将失败。
此方法遵循继承层次结构,因此,如果期望的类型为"异常",而实际类型为" RuntimeException",则断言将通过。
@Test @DisplayName("assertThrows Examples") void test_assertThrows() { assertThrows(RuntimeException.class, () -> { throw new RuntimeException(); }); assertThrows(Exception.class, () -> { throw new RuntimeException(); }); //this will fail //assertThrows(IOException.class, () -> {throw new RuntimeException();}); //assertThrows(IOException.class, () -> {throw new RuntimeException();}, "assertThrows Failure Message"); }
assertDoesNotThrow()
断言所提供的可执行文件的执行不会引发任何异常。
该方法以org.junit.jupiter.api.function.Executable实例作为参数。
可执行文件是一个功能性接口,可用于实现可能抛出Throwable的任何通用代码块。
class MyExecutable implements Executable { @Override public void execute() throws Throwable { System.out.println("Hello There!"); } }
如果我们不打算重用它,则可以使用lambda表达式创建Executable。
@Test @DisplayName("assertDoesNotThrow Examples") void test_assertDoesNotThrow() { assertDoesNotThrow(new MyExecutable()); assertDoesNotThrow(new MyExecutable(), "assertDoesNotThrow custom message"); }
assertAll()
断言所有提供的可执行文件均不会引发异常。
我们可以传递数组,流或者"可执行"对象的集合。
@Test @DisplayName("assertAll Examples") void test_assertAll() { assertAll(Arrays.asList(new MyExecutable())); assertAll(new MyExecutable()); assertAll(Stream.of(new MyExecutable())); //assertAll("My Executables Heading Error Message", () -> {throw new Exception("Hi");}); }
assertTimeout()
声明所提供的可执行文件的执行在超过给定的超时之前完成。
该可执行文件将在与调用代码相同的线程中执行。
因此,如果超过了超时时间,可执行文件的执行将不会被抢先中止。
@Test @DisplayName("assertTimeout Examples") void test_assertTimeout() { assertTimeout(Duration.ofSeconds(1), new MyExecutable()); assertTimeout(Duration.ofSeconds(3), () -> { Thread.sleep(2000); System.out.println("Done"); }); //this will fail /* assertTimeout(Duration.ofNanos(1), () -> { Thread.sleep(20); System.out.println("Done"); }, "assertTimeout Failure Message: Too less time to execute"); */ }
assertTimeoutPreemptively()
声明所提供的可执行文件的执行在超过给定的超时之前完成。
该可执行文件将在与调用代码不同的线程中执行。
此外,如果超过了超时时间,可执行文件的执行将被抢先中止。
@Test @DisplayName("assertTimeoutPreemptively Examples") void test_assertTimeoutPreemptively() { assertTimeoutPreemptively(Duration.ofSeconds(1), new MyExecutable()); assertTimeoutPreemptively(Duration.ofMillis(100), () -> System.out.println("Hello There")); //this will timeout for sure //assertTimeoutPreemptively(Duration.ofNanos(1), () -> System.out.println("Hello There")); /* assertTimeoutPreemptively(Duration.ofSeconds(1), () -> { throw new RuntimeException(""); }); */ assertTimeoutPreemptively(Duration.ofSeconds(1), new MyExecutable(), "MyExecutable didn't completed within 1 second"); assertTimeoutPreemptively(Duration.ofSeconds(1), new MyExecutable(), () -> { return "MyExecutable didn't completed within 1 second"; }); /* assertTimeoutPreemptively(Duration.ofSeconds(2), () -> { throw new RuntimeException(""); }, "MyExecutable didn't completed within 2 second"); */ }