학습 목표
1. JUnit의 기능들 알아보기 - 테스트 클래스 활용법
2. Assertions 알아보기
1. JUnit의 기능들 알아보기 - 테스트 클래스 활용법
📌Before / After
@BeforeEach
테스트 클래스에서 command + N > SetupMethod
각각의 테스트가 실행되기 전에 실행되는 메서드
@AfterEach
테스트 클래스에서 command + N > TearDownMethod
각각의 테스트 코드가 실행된 후에 실행되는 메서드
@BeforeAll
테스트 클래스에서 command + N > BeforClass Method
모든 테스트 코드가 실행되기 전에 최초로 수행
@AfterAll
테스트 클래스에서 command + N > AfterClass Method
모든 테스트 코드개 수행된 후 마지막으로 수행
package com.sparta.junit5practice;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
public class BeforeAfterTest {
//테스트 클래스에서 command + N > SetupMethod
@BeforeEach //각각의 테스트가 실행되기 전에 실행되는 메서드
void setUp() {
System.out.println("각각의 테스트 코드가 실행되기 전에 수행");
}
//테스트 클래스에서 command + N > SetupMethod
@AfterEach
void tearDown() {
System.out.println("각각의 테스트 코드가 실행된 후에 실행\n");
}
//테스트 클래스에서 command + N > BeforClass Method
@BeforeAll
static void beforeAll() {
System.out.println("모든 테스트 코드가 실행되기 전에 최초로 수행\n");
}
//테스트 클래스에서 command + N > AfterClass Method
@AfterAll
static void afterAll() {
System.out.println("모든 테스트 코드개 수행된 후 마지막으로 수행");
}
@Test
void test1() {
System.out.println("테스트 코드 작성 1");
}
@Test
void test2() {
System.out.println("테스트 코드 작성2");
}
}

📌Nested() :주제별로 그룹지어서 테스트하고 싶을 때
package com.sparta.junit5practice;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
public class CustromTest {
@Test
@DisplayName("테스트의 내용을 한눈에 알아볼 수 있게 네이밍해줄 때")
void test1() {
System.out.println("테스트 내용 빠르게 파악");
}
@Nested
@DisplayName("주제 별로 테스트를 그룹지어서 파악하기 좋습니다.")
class Test1 {
@Test
@DisplayName("Test1 - test1()")
void test1() {
System.out.println("Test1.test1");
}
@Test
@DisplayName("Test1 - test2()")
void test2() {
System.out.println("Test1.test2");
}
}
@Nested
@DisplayName("Test2 다른 주제")
class Test2 {
@Test
@DisplayName("Test2 - test1()")
void test1() {
System.out.println("Test2.test1");
}
@Test
@DisplayName("Test2 - test2()")
void test2() {
System.out.println("Test2.test2");
}
}
}

📌@Order()
코드를 차례대로 입력해도 메서드를 선언한 순서대로 실행되지 않는다.
따라서 테스트를 메서드 단위로 순서를 매겨야 할때 @Order 사용
package com.sparta.junit5practice;
import org.junit.jupiter.api.*;
public class CustromTest {
@Test
@DisplayName("테스트의 내용을 한눈에 알아볼 수 있게 네이밍해줄 때")
void test1() {
System.out.println("테스트 내용 빠르게 파악");
}
@Nested
@DisplayName("주제 별로 테스트를 그룹지어서 파악하기 좋습니다.")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class Test1 {
@Order(1)
@Test
@DisplayName("Test1 클래스")
void test() {
System.out.println("\nTest1 클래스");
}
@Order(3)
@Test
@DisplayName("Test1 - test1()")
void test1() {
System.out.println("Test1.test1");
}
@Order(2)
@Test
@DisplayName("Test1 - test2()")
void test2() {
System.out.println("Test1.test2");
}
}
@Nested
@DisplayName("Test2 다른 주제")
class Test2 {
@Test
@DisplayName("Test2 - test1()")
void test1() {
System.out.println("Test2.test1");
}
@Test
@DisplayName("Test2 - test2()")
void test2() {
System.out.println("Test2.test2");
}
}
}
📌RepeatTest
package com.sparta.junit5practice;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.RepetitionInfo;
public class RepeatTest {
//메서드를 반복해서 수행 , value : 몇번 돌릴지
// getCurrentRepetition = 몇번 돌아갔는지 / getTotalRepetitions = 총 몇번 돌릴지
@RepeatedTest(value = 5, name = "반복 테스트 {currentRepetition} / {totalRepetitions}")
void repeatTest(RepetitionInfo info) {
System.out.println("테스트 반복 : " + info.getCurrentRepetition() + " / " + info.getTotalRepetitions());
}
}

📌 ParameterizedTest
//전달되는 파라미터 수만큼 테스트메서드가 수행됨
@DisplayName("파라미터 값 활용하여 테스트 하기")
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 4, 5, 6, 7, 8, 9}) //전달해주고 싶은 파라미터 값
void parameterTest(int num) {
System.out.println("5 * num = " + 5 * num);
}

2. Assertions
기능 검증하기
검증할 클래스 생성
Calculator - 계산기 기능
package com.sparta.junit5practice;
public class Calculator {
public Double operate(double num1, String op, double num2) {
switch (op) {
case "*":
return num1 * num2;
case "/":
if (validateNum(num2)) {
return num1 / num2;
} else {
return null;
}
case "+":
return num1 + num2;
case "-":
return num1 - num2;
default:
throw new IllegalArgumentException("잘못된 연산자입니다.");
}
}
public boolean validateNum(double num) {
if (num == 0) {
return false;
} else {
return true;
}
}
}
Assertions 를 이용한 검증
📌 assertEquals / assertNotEquals
package com.sparta.junit5practice;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class AssertionTest {
Calculator calculator;
@BeforeEach
void setUp() { //테스트 실행 전에 객체를 하나씩 생성하게끔 설정
calculator = new Calculator();
}
@Test
@DisplayName("assertEquals")
void test1() { //성공
Double result = calculator.operate(5, "/", 2);
assertEquals(2.5, result);
}
@Test
@DisplayName("assertEquals - Supplier")
void test1_1() {
Double result = calculator.operate(5, "/", 0);
// 테스트 실패 시 메시지 출력 (new Supplier<String>())
assertEquals(2.5, result, () -> "연산자 혹은 분모가 0이 아닌지 확인해보세요!");
}
@Test
@DisplayName("assertNotEquals")
void test1_2() {
Double result = calculator.operate(5, "/", 0);
assertNotEquals(2.5, result); //예측이 틀려야 통과
}
}
두번째 테스트 -> 실패 시 동작을 알아보자
@Test
@DisplayName("assertEquals - Supplier")
void test1_1() {
Double result = calculator.operate(5, "/", 0);
// 테스트 실패 시 메시지 출력 (new Supplier<String>())
assertEquals(2.5, result, () -> "연산자 혹은 분모가 0이 아닌지 확인해보세요!");
}

📌 assertTrue / assertFalse
//boolean 값을 검증하고 싶을 때
@Test
@DisplayName("assertTrue 와 assertFalse")
void test2() {
assertTrue(calculator.validateNum(9)); //true를 반환하는지
assertFalse(calculator.validateNum(0)); //false를 반환하는지
}

📌 assertNull, assertNotNull
//null 여부 체크
@Test
@DisplayName("assertNotNull 과 assertNull")
void test3() {
Double result1 = calculator.operate(5, "/", 2);
assertNotNull(result1);
Double result2 = calculator.operate(5, "/", 0);
assertNull(result2);
}
📌 assertThrows
//exception 테스트
@Test
@DisplayName("assertThrows") // (예상하는 클래스 타입 , 실제 테스트)
void test4() {
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> calculator.operate(5, "?", 2));
assertEquals("잘못된 연산자입니다.", exception.getMessage()); //예측하는 메시지와 실제 메시지가 일치하는지 체크
}
오늘의 코멘트
내가 구현한 기능이 원활하게 작동하기 위해선 테스트가 필요하다. 코드가 로컬에선 잘 작동해도, 실제 서비스를 제공하다보면 어떤 오류가 발생할지 모르기 때문이다. junit에서 많은 테스트 기능들을 제공하는 것은 알았지만, 한번 더 공부하면서 내가 생각하는 것 이상의 디테일한 기능들이 존재한다는 것을 알게 되었다.
모든 기능을 다 공부하고 써볼 수는 없으므로, 개발을 하며 직접 테스트를 진행하면서 필요한 기능들을 찾아보고 공부해야 겠다.
'SPRING > Test' 카테고리의 다른 글
| 251021 (화) JUnit 테스트 생명주기 완벽 이해하기 — @BeforeAll, @AfterAll, @BeforeEach, @AfterEach, 테스트 인스턴스 (0) | 2025.10.21 |
|---|