단정(Assert) 메서드
테스트 케이스의 수행 결과를 판별하는 메서드를 말한다.
아래에서 대표적인 단정 메서드 몇개만 알아보도록 하자.
참고로 이는 모두 org.junit.jupiter.api.Assertions 패키지에 있다.
assertNotNull(Object actual)
해당 객체가 null이 아닌지 검사하는 메서드이다.
@Test
@DisplayName("공부합시다")
void 공부하자() {
String study = "study";
assertNotNull(study);
}
assertEquals(expect, actual)
객체 actual이 expect와 같은 값을 가지는지 확인하는 메서드이다.
@Test
@DisplayName("공부합시다!")
void 공부하러가자() {
String study = "";
assertEquals("", study, "study는 빈 String이다.");
}
assertTrue(boolean)
주어진 조건이 참인지 확인하는 메서드이다.
@Test
@DisplayName("공부할까?")
void 공부하러갈까() {
String study = "okay";
assertTrue(study.contains("ok"), "study에는 \"ok\"가 포함돼있다.");
}
assertAll(executable ... )
모든 확인 구문들을 테스트하는 메서드이다.
아래와 같이 여러개의 단언문을 사용할때 앞선 테스트가 실패하면 다음 테스트는 실행되지 않는다.
때문에 다음 테스트가 실패했는지 알 수 없다.
@Test
@DisplayName("공부안하러가자")
void 공부안하러가자() {
String study = "";
assertEquals("study", study, "study는 \"study\"와 같다."); // 실패!
assertTrue(study.length() == 0, "공부 주제가 없다.");
}
이럴때 assertAll() 메서드를 사용하면 모든 테스트의 결과를 확인할 수 있다.
@Test
@DisplayName("공부안하러가자")
void 공부안하러가자() {
String study = "";
assertAll(
() -> assertEquals("study", study, "study는 \"study\"와 같다."), // 첫번째 executable
() -> assertTrue(study.length() != 0, "공부 주제가 없다.") // 두번째 executable
);
}
💡 파라미터의 executable은 JUnit API 중 추상 메서드가 하나인 인터페이스인 '함수형 인터페이스' Executable를 나타낸다. Executable은 파라미터가 없고 리턴 타입이 void인 execute() 메서드를 정의하고 있으며, 위 코드에서는 람다(lambda) 표현식으로 assertAll() 메서드의 파라미터가 있는 것을 볼 수 있다.
추후 함수형 인터페이스, 람다 표현식에 대해 별도의 포스팅을 한 후 링크를 걸어둘테니 참고 바란다.
assertThrows(expectedType, executable)
executable에서 expectedType의 예외가 발생했는지 확인하는 메서드이다.
@Test
@DisplayName("아이디 중복으로 인한 유저 등록 실패")
public void FailToUserCreateIfDuplicateLoginId() throws Exception {
// "loginid123" 이라는 아이디를 찾으면 UserDTOAllField를 return 해라.
given(userServiceImpl.findUserByLoginId("loginid123")).willReturn(UserDTOAllField);
// userServiceImpl.addUser에서 DuplicateKeyException이 발생했는지 확인한다.
assertThrows(DuplicateKeyException.class,
() -> {
userServiceImpl.addUser(UserDTOAllField);
}
);
}
assertTimeout(duration, executable)
특정 시간 안에 실행이 완료되는지 확인한다.
두번째 매개변수의 람다문이 종료되야 테스트가 끝난다.
@Test
@DisplayName("공부 이만큼 하자")
void 공부_이만큼_하자() {
assertTimeout(Duration.ofMillis(100), () -> { // 100 밀리초 안에 끝나길 바랐는데
Thread.sleep(300); // 300 밀리초 스레드를 재운다.
});
}
라이프사이클(Lifecycle) 메서드
JUnit4와 마찬가지로 JUnit5에도 라이프사이클 메서드가 존재한다.
4개의 어노테이션이 존재하는데 각각에 대해서 알아보도록 하겠다.
@BeforeAll
- 테스트 클래스 기준으로 테스트 메서드들이 실행되기전 실행
- JUnit4의 @BeforeClass 역할
@BeforeEach
- 각 테스트 메서드가 실행되기전 실행
- JUnit4의 @Before 역할
@AfterAll
- 테스트 클래스 기준으로 테스트 메서드들이 실행된 후 실행
- JUnit4의 @AfterClass 역할
@AfterEach
- 각 테스트 메서드가 실행된 후 실행
- JUnit4의 @After 역할
코드를 통한 확인
아래 코드는 JUnit5 공식 사이트를 참고한 것이다.
class StandardTests {
@BeforeAll
static void initAll() {
System.out.println("initAll");
}
@BeforeEach
void init() {
System.out.println("init");
}
@Test // 테스트 메서드
void succeedingTest() {
System.out.println("succeedingTest");
}
@Test // 테스트 메서드
void failingTest() {
fail("a failing test");
}
@Test // 테스트 메서드이지만 Disabled 돼서 실행 안됨
@Disabled("for demonstration purposes")
void skippedTest() {
// not executed
System.out.println("skippedTest");
}
@Test // 테스트 메서드
void abortedTest() {
assumeTrue("abc".contains("Z"));
fail("test should have been aborted");
}
@AfterEach
void tearDown() {
System.out.println("tearDown");
}
@AfterAll
static void tearDownAll() {
System.out.println("tearDownAll");
}
}
아래 실행결과를 정리하면 다음과 같다.
- @BeforeAll 이 적용된 메서드 initAll()이 가장 처음 실행되므로 "initAll" 1회 출력
- @BeforeEach 이 적용된 메서드 init()이 모든 @Test 메서드마다 직전에 실행되므로 "init" 3회 출
- @AfterEach 이 적용된 메서드 tearDown()이 모든 @Test 메서드마다 직후에 실행되므로 "tearDown" 3회 출력
- @AfterAll 이 적용된 메서드 tearDownAll()이 가장 마지막에 실행되므로 "tearDownAll" 1회 출력
이를 보기 쉽게 도식화 해봤다.
출처
단정(Assert)
junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/Assertions.html
라이프사이클(Lifecycle) 메서드 참고
junit.org/junit5/docs/current/user-guide/#writing-tests-classes-and-methods
'테스트 코드 > JUnit5' 카테고리의 다른 글
JUnit의 개념과 장점, 단위 테스트의 개념과 장점, 단위/통합/기능 테스트 (0) | 2021.04.20 |
---|