💡 @Test - JUnit에서 메서드를 테스트 메소드로 표시하는 데 사용됩니다. - 테스트 클래스가 실행되면 JUnit은 @Test로 주석이 달린 메소드를 개별적인 테스트 케이스로 식별하여 실행합니다.
1.1. 테스트 수행구조
💡 테스트 수행구조 - 테스트를 시작하면 @Test 어노테이션을 통해 testSum()이라는 함수를 수행시키고 종료합니다.
1.2. 코드 사용예시
💡 코드 사용예시
- 해당 테스트에서는 두 숫자의 합이 맞는지 여부를 확인하는 테스트를 구성하였습니다. - a + b의 값과 expectedSum값을 비교했을 때 해당 결과값이 맞는지에 대해 확인합니다.
package com.adjh.multiflexapi;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
/**
* 메인 테스트
*
* @author : lee
* @fileName : MultiFlexApiApplicationTests
* @since : 12/6/23
*/
class MultiFlexApiApplicationTests {
@Test
@DisplayName("두 숫자의 합 테스트")
void testSum() {
int a = 5;
int b = 7;
int expectedSum = 12;
int actualSum = a + b;
Assertions.assertEquals(expectedSum, actualSum);
}
}
1.3. 결과 확인
💡 해당 값이 맞는 경우 : ‘테스트 통과’ 메시지를 출력합니다.
💡 해당 값이 틀린 경우 : ‘테스트 실패’ 메시지를 출력합니다.
2. 클래스/테스트 전후 수행 테스트 : @BeforeAll, @AfterAll, @BeforeEach, @AfterEach
💡 클래스/테스트 전후 수행 테스트
- @BeforeAll, @AfterAll 어노테이션을 이용하여 테스트 클래스의 시작/후에 단 한번 호출이 됩니다. - @BeforeEach, @AfterEach 어노테이션을 이용하여 매 @Test 전후에 호출이 됩니다.
어노테이션
설명
@BeforeAll
JUnit 테스트 클래스 내에서 모든 테스트 메소드 실행 전에 한 번 실행되는 메소드를 정의하는 데 사용됩니다. 보통 테스트 환경의 설정이나 초기화에 사용됩니다.
@AfterAll
JUnit 테스트 클래스 내에서 모든 테스트 메소드 실행 후에 한 번 실행되는 메소드를 정의하는 데 사용됩니다. 주로 사용한 리소스를 정리하거나 테스트 환경을 종료하는 데 사용됩니다.
@BeforeEach
JUnit 테스트 클래스 내의 각 테스트 메소드마다 실행되는 메소드를 정의하는 데 사용됩니다. 주로 각 테스트의 준비 작업이나 초기화에 사용됩니다.
@AfterEach
JUnit 테스트 클래스 내의 각 테스트 메소드 실행 후에 실행되는 메소드를 정의하는 데 사용됩니다. 주로 각 테스트의 후처리 작업이나 정리 작업에 사용됩니다.
2.1. 테스트 수행 구조
💡 테스트 수행구조
1. 테스트를 시작하면 @BeforeAll 어노테이션을 통해 setUpBeforeClass() 함수가 수행됩니다.
2. @Test 어노테이션을 통해 수행되기 이전에 @BeforEach의 setUp() 함수가 수행됩니다.
3. @Test 어노테이션을 통해 testEqualsSum() 함수가 수행됩니다.
4. @Test 어노테이션을 통해 수행된 후 @AfterEach의 cleanUp() 함수가 수행됩니다.
5. 동일한 과정으로 @Test 어노테이션을 통해 수행되기 이전에 @BeforEach의 setUp() 함수가 수행됩니다.
6. 동일한 과정으로 @Test 어노테이션을 통해 testIsNotNull() 함수가 수행됩니다.
7. 동일한 과정으로 @Test 어노테이션을 통해 수행된 후 @AfterEach의 cleanUp() 함수가 수행됩니다.
8. 최종 테스트 종료 이전에 @AfterAll 어노테이션을 통해 cleanUpAfterClass() 함수가 수행됩니다.
2.2. 코드 사용예시
package com.adjh.multiflexapi;
import com.adjh.multiflexapi.model.CodeDto;
import com.adjh.multiflexapi.service.CodeService;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
/**
* 메인 테스트
*
* @author : lee
* @fileName : MultiFlexApiApplicationTests
* @since : 12/6/23
*/
class MultiFlexApiApplicationTests {
@Test
@DisplayName("두 숫자의 합 테스트")
void testEqualsSum() {
System.out.println("[+] @test assertEquals Annotation");
int a = 5;
int b = 7;
int expectedSum = 12;
int actualSum = a + b;
Assertions.assertEquals(expectedSum, actualSum);
}
@Test
@DisplayName("Object NULL 여부 테스트")
void testIsNotNull() {
Object obj = null;
Assertions.assertNull(obj);
System.out.println("[+] @test assertNull Annotation");
}
// 각 테스트 메소드 실행 전에 실행되는 메소드를 정의하는 어노테이션
@BeforeEach
void setUp() {
System.out.println("@BeforeEach Annotation");
}
// 각 테스트 메소드 실행 후에 실행되는 메소드를 정의하는 어노테이션
@AfterEach
void cleanUp() {
System.out.println("@AfterEach Annotation");
}
// 클래스 내의 모든 테스트 메서드 실행 전에 한 번 호출되는 메서드
@BeforeAll
static void setUpBeforeClass() {
System.out.println("@BeforeAll Annotation");
}
// 클래스 내의 모든 테스트 메서드 실행 후에 한 번 호출되는 메서드
@AfterAll
static void cleanUpAfterClass() {
System.out.println("@AfterAll Annotation");
}
}
2.3. 수행 결과
💡 수행 결과
- @Test로 구성한 두 개의 메서드가 성공적으로 수행되었습니다. - @BeforeAll, @AfterAll의 경우는 테스트의 시작 전후에 한 번씩만 수행되었고@BeforeEach, @AfterEach의 경우는 @Test로 구성한 메서드의 전후에 각각 수행이 되었습니다.
3. Given-When-Then 패턴 시나리오 테스트
💡 Given-when-then 패턴 시나리오 테스트하기
- @Test를 선언한 메서드에서 시나리오를 구성하기 위해 Given-When-Then 패턴을 통하여서 시나리오를 구성합니다.
섹션
설명
Given : 설정
테스트의 초기 상태 또는 사전 조건을 설정합니다. 입력 데이터나 테스트가 실행될 문맥을 지정합니다.
When : 동작
테스트되는 동작 또는 이벤트를 설명합니다. 테스트되는 특정 메서드나 동작을 나타냅니다.
Then : 검증
"When" 섹션에서 설명한 동작으로 인해 기대되는 결과 또는 동작을 정의합니다.
3.1. 테스트 수행구조
💡 테스트 수행구조
1. 테스트를 시작하면 @BeforeAll 어노테이션을 통해 setUpBeforeClass() 함수가 수행됩니다.
2. @Test 어노테이션을 통해 testAddingTwoNumbers() 함수가 수행됩니다.
3. @Test 어노테이션을 통해 testDividingTwoNumbers() 함수가 수행됩니다.
4. 테스트를 종료하면서 @AfterAll 어노테이션을 통해 cleanUpAfterClass() 함수가 수행됩니다.
3.2. 코드 사용예시
package com.adjh.multiflexapi;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
* 중첩 테스트 클래스
*
* @author : lee
* @fileName : CalculatorTests
* @since : 12/7/23
*/
class CalculatorTests {
@BeforeAll
static void setUpBeforeAll() {
System.out.println("@BeforeAll Annotation");
}
@Test
void testAddingTwoNumbers() {
// given : 초기 상태 지정
int a = 2;
int b = 3;
// when : 테스트 동작 정의
int result = Calculator.add(a, b);
// then : 검증
int expected = 5;
Assertions.assertEquals(expected, result);
System.out.println("Test for adding two numbers passed");
}
@Test
void testDividingTwoNumbers() {
// given : 초기 상태 지정
int a = 10;
int b = 2;
// when : 테스트 동작 정의
int result = Calculator.divide(a, b);
// then : 검증
int expected = 5;
Assertions.assertEquals(expected, result);
System.out.println("Test for dividing two numbers passed");
}
@AfterAll
static void cleanUpAfterAll() {
System.out.println("@AfterAll Annotation");
}
}
class Calculator {
static int add(int a, int b) {
return a + b;
}
static int divide(int a, int b) {
return a / b;
}
}
3.3. 수행 결과
💡 수행 결과
- 시작 전후에 @BeforAll, @AfterAll로 지정한 메서드가 실행이 되었습니다. - @Test로 지정한 testAddingTwoNumbers(), testDividingTwoNumbers() 함수가 실행이 되었습니다.
4. 중첩된 테스트 : @Nested
💡 중첩된 테스트
- 클래스 내에서 테스트가 많이 있어서 가독성이 떨어지는 경우 클래스 내에 클래스를 구현하여서 @Nested 어노테이션을 통해서 테스트 별로 묶어서 수행하는 방법입니다. - 이를 통해 테스트들을 구조화하여 가독성을 향상하는데 도움을 줍니다.
💡 @Nested - JUnit에서 중첩된 테스트 클래스를 작성하는 데 사용됩니다. 중첩된 테스트 클래스는 특정 테스트 그룹을 더 잘 구조화하고 테스트 코드의 가독성을 향상시키는 데 도움이 됩니다. - 중첩된 테스트 클래스는 내부 클래스로 선언되며, 외부 테스트 클래스의 인스턴스와 상호작용할 수 있습니다. 이를 통해 외부 테스트 클래스의 상태를 공유하거나 테스트 케이스 간의 의존성을 관리할 수 있습니다
4.1. 테스트 수행구조
💡 테스트 수행구조 - @Nested 어노테이션이나 @Test 어노테이션은 순서를 보장하지 않기에 구성한 예시로 확인해 주시면 좋을 것 같습니다.
1. 테스트를 시작하면 @Nested 어노테이션을 통해 CalcTests Class가 수행이 됩니다.
2. CalcTests 클래스 내에서 @Test 어노테이션을 확인하여 testSum() 메서드가 수행이 됩니다.
3. CalcTests 클래스 내에서 @Test 어노테이션을 확인하여 testAddingTwoNumbers() 메서드가 수행이 됩니다.
4. CalcTests 클래스 내에서 @Test 어노테이션을 확인하여 testDividingTwoNumbers() 메서드가 수행이 됩니다.
5. 다음으로 @Nested 어노테이션을 통해 IsNotNullTests Class가 수행이 됩니다.
6. IsNotNullTests 클래스 내에서 testsNotNull() 메서드가 수행됩니다.
7. 테스트가 종료됩니다.
4.2. 코드 사용 예시
package com.adjh.multiflexapi;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
/**
* 중첩화 된 테스트
*
* @author : lee
* @fileName : NestedTests
* @since : 12/8/23
*/
class NestedTests {
@Nested
class CalcTests {
@Test
@DisplayName("두 숫자의 합 테스트")
void testSum() {
int a = 5;
int b = 7;
int expectedSum = 12;
int actualSum = a + b;
Assertions.assertEquals(expectedSum, actualSum);
}
@DisplayName("두 숫자의 합 테스트")
@Test
void testAddingTwoNumbers() {
// given : 초기 상태 지정
int a = 2;
int b = 3;
// when : 테스트 동작 정의
int result = Calculator.add(a, b);
// then : 검증
int expected = 5;
Assertions.assertEquals(expected, result);
System.out.println("Test for adding two numbers passed");
}
@Test
@DisplayName("두 수의 값 나누기 ")
void testDividingTwoNumbers() {
// given : 초기 상태 지정
int a = 10;
int b = 2;
// when : 테스트 동작 정의
int result = Calculator.divide(a, b);
// then : 검증
int expected = 5;
Assertions.assertEquals(expected, result);
System.out.println("Test for dividing two numbers passed");
}
}
@Nested
class IsNotNullTest {
@Test
@DisplayName("Object NULL 여부 테스트")
void testIsNotNull() {
Object obj = null;
Assertions.assertNull(obj);
System.out.println("[+] @test assertNull Annotation");
}
}
}
4.3. 수행 결과
💡 수행 결과
- NestedTests 클래스 안에 CalcTests와 IsNotNullTest 클래스가 존재하는데, 각각 모두 수행이 됨을 확인하였습니다.
3) JUnit 5 사용 예시 -2: 서비스 테스트
1. @SpringBootTest 어노테이션을 사용하여 테스트 : @SpringBootTest
💡 @SpringBootTest 어노테이션을 사용하여 테스트
- @SpringBootTest를 사용하면 애플리케이션 컨텍스트를 로딩하고 필요한 빈을 초기화하는 등 테스트에 필요한 설정과 의존성을 설정하는데 도움이 됩니다.
💡 @SpringBootTest
- 애플리케이션의 전체 컨텍스트를 로드하여 테스트할 수 있습니다. 이를 통해 실제 환경과 유사한 설정에서 테스트를 수행하고 각각의 컴포넌트가 상호작용하는 방식을 확인할 수 있습니다.
- 애플리케이션의 다양한 컴포넌트를 테스트할 수 있으며, 외부 서비스와의 상호작용, 데이터베이스 연동 등을 포함한 실제 환경에서의 동작을 확인할 수 있습니다.
💡 클래스에 @SpringBootTest 어노테이션을 선언하면 @Test을 수행하면서 아래와 같이 로컬 서버가 수행되면서 테스트가 진행되는 것을 확인할 수 있습니다.
1.1. 테스트 수행 구조
💡 테스트 수행구조
1. 클래스 내에 @SpringBootTest 어노테이션을 선언하였습니다. (*이는 @Test 어노테이션 수행직전에 수행이 됩니다)
2. 테스트를 시작하면 @BeforeAll 어노테이션을 통해 setUpBeforeClass() 함수가 수행됩니다.
3. @Test 어노테이션이 수행되기 직전에 로컬 서버가 실행이 되어 각각의 컨텍스트를 로드해 옵니다.
4. @Test 어노테이션을 통해 testIsNotNullCodeList() 함수가 수행됩니다.
5. 테스트를 종료하면서 @AfterAll 어노테이션을 통해 cleanUpAfterClass() 함수가 수행됩니다.
2.2. 코드 사용 예시
💡 코드 사용 예시
- 해당 코드에서는 CodeService를 주입받아서 값을 구성하여 서비스를 호출하는 테스트를 구성하였습니다.