Java 단위테스트 작성에는 기본적으로 2가지 라이브러리가 사용됩니다.
JUnit 하나로도 충분한 단위 테스트를 작성할 수 있다. 그러나 JUnit에서 제공하는 assertEquals()와 같은 메소드는 AssertJ에 있는 메소드에 비해 가독성이 떨어집니다.
그러므로, JUnit5 와 AssertJ 조합이 많이 사용 됩니다.
이번 리뷰는 JUnit을 활용한 테스트 코드를 작성해 보겠습니다.
JUnit Platform
JUnit Platform은 JVM에서 테스트를 시작하기 위한 뼈대 역할
테스트를 발견하고 테스트 계획을 생성하는 테스트 엔진(TestEngine)의 인터페이스를 보유한다
테스트 엔진은 테스트를 발견하고 테스트를 수행하며, 그 결과를 보고하는 역할을 수행한다
또한 각종 IDE와의 연동을 보조 하는 역할을 수행한다.(IDE 콘솔 출력 등) Platform에는 TestEngine API, Console Launcher, JUnit 4 Based Runner 등이 포함
JUnit Jupiter
테스트 엔진 API의 구현체를 포함하고 있으며, JUnit 5에서 제공하는 Jupiter 기반의 테스트를 실행하기 위한 테스트 엔진을 가지고 있다
테스트의 실제 구현체는 별도 모듈의 역할을 수행하는데 그중 하나가 Jupiter Engine 이다. Jupiter Engine은 Jupiter API를 활용해서 작성한 테스트 코드를 발견하고 실행하는 역할을 수행
JUnit Vintage
JUnit 3, 4에 대한 테스트 엔진 API를 구현하고 있다
기존에 작성된 JUnit 3,4 버전의 테스트 코드를 실행할 때 사용되며 Vintage Engine을 포함하고 있다.
- JUnit의 구조 그림
<이제 간단한 테스트 코드로 실행 해보자.>
'''xml
... 생략 ...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
... 생략 ...
''' 인텔리제이에서 pom.xml에 test 디펜던시를 추가한다.
추가하면 
그림 처럼 의존성을 가지게 된다.
JUnit 5 : 자바 애플리케이션의 단위 테스트를 지원한다
Spring Test & Spring Boot Test : 스프링 부트 애플리케이션에 대한 유틸리티와 통합 테스트를 지원
AssertJ : 다양한 단정문(assert)을 지원하는 라이브러리
Hamcrest : Matcher를 지원하는 라이브러리이다.
Mockito : 자바 Mock 객체를 지원하는 프레임 워크
JSONassert : JSON용 단정문 라이브러리이다
JsonPath : JSON용 XPath를 지원한다
생명 주기와 관련된 어노테이션
@Test : 테스트 코드를 포함한 메서드를 정의한다
@BeforeAll : 테스트를 시작하기 전에 호출되는 메서드를 정의한다
@BeforeEach : 각 테스트 메거드가 실행되기 전에 동작하는 메서드를 정의한다
@AfterAll : 테스트를 종요하면서 호출되는 메서드를 정의한다
@AfterEach : 각 테스트 메서드가 종료되면서 호출되는 메서드를 정의한다
'''java
package com.springboot.test;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
public class TestLifeCycle {
@BeforeAll
static void beforeAll() {
System.out.println("## BeforeAll Annotation 호출 ##");
System.out.println();
}
@AfterAll
static void afterAll() {
System.out.println("## afterAll Annotation 호출 ##");
System.out.println();
}
@BeforeEach
void beforeEach() {
System.out.println("## beforeEach Annotation 호출 ##");
System.out.println();
}
@AfterEach
void afterEach() {
System.out.println("## afterEach Annotation 호출 ##");
System.out.println();
}
@Test
void test1() {
System.out.println("## test1 시작 ##");
System.out.println();
}
@Test
@DisplayName("Test Case 2!!!")
void test2() {
System.out.println("## test2 시작 ##");
System.out.println();
}
@Test
@Disabled
void test3() {
System.out.println("## test3 시작 ##");
System.out.println();
}
}
''' 이 테스트 코드를 실행하면

다음과 같은 결과를 볼수 있다.
쉽게 정리하면
1. beforeAll과 afterAll은 전체 메서드 시작과 끝에 호출
2. beforeEach 와 afterEach는 한 메서드 시작과 끝에 호출
즉 a,b,c 메서드가 있다고 가정
beforeAll - 전체메서드 시작 전
/////////////////////////////////////////
beforeEach - 한 메서드 시작 전
a()
afterEach는 - 한메서드 종료 후
/////////////////////////////////////////
beforeAll - 전체메서드 시작 전
b()
afterEach는 - 한메서드 종료 후
/////////////////////////////////////////
beforeAll - 전체메서드 시작 전
c()
afterEach는 - 한메서드 종료 후
/////////////////////////////////////////
afterAll - - 전체메서드 종료 후
이렇게 나누어 진다.