GrowMe

스프링부트에서 JUnit 사용하기 본문

Testing skills

스프링부트에서 JUnit 사용하기

오늘도 타는중 2022. 7. 19. 14:30
JUnit
# Junit이란
부가기능
AOP 사용법
Advice
PointCut

*JUnit이란?

  • Java 언어로 만들어진 애플리케이션을 테스트 하기 위한 오픈 소스 테스트 프레임워크
  • Java의 표준 테스트 프레임워크라 불리운다.
  • Java 8부터 JUnit 5 사용이 가능하다.

*스프링부트에서 JUnit 사용법 (Gradle 기준)

- 의존성 추가

dependencies {
	..
testImplementation 'org.springframework.boot:spring-boot-starter-test'
	..
}

- JUnit을 사용한 테스트 케이스의 기본 구조

import org.junit.jupiter.api.Test;

public class JunitDefaultStructure {
    @Test
    public void test1() {
        // 테스트 하고자 하는 대상에 대한 테스트 로직 작성
    }
    
    @Test
    public void test2() {
        // 테스트 하고자 하는 대상에 대한 테스트 로직 작성
    }
}
  • @Test : 해당 메서드가 테스트 메서드가 되며, 테스트 메서드를 가진 클래스 JunitDefaultStructure는 테스트 클래스가 된다.
  • 테스트 메서드는 abstract와 private 선언하면 안되며, 반환 값이 없어야 한다.

- Assertion 메서드

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class AssertionTest {
    @DisplayName("Hello JUnit Test") 
    @Test
    public void assertionTest() {
        String expected = "Hello, JUnit";
        String actual = "Hello, JUnit";

        assertEquals(expected, actual); 
    }
    
    @DisplayName("AssertionNull() Test")
    @Test
    public void assertNotNullTest() {
        String currencyName = getCryptoCurrency("ETH");
        assertNotNull(currencyName, "should be not null");
    }
    private String getCryptoCurrency(String unit) {
        return CryptoCurrency.map.get(unit);
    }
    
    @DisplayName("throws NullPointerException when map.get()")
    @Test
    public void assertionThrowExceptionTest() {
        assertThrows(NullPointerException.class, () -> getCryptoCurrency("XRP"));
    }
}

 

  • @DisplayName : 테스트 케이스 실행 시, 실행 창에 표시되는 이름을 지정
  • assertEquals() : (기대하는 값, 실제 값) 이 서로 같은지를 검증
  • assertNotNull() : (테스트 대상 객체, 실패 시 표시할 메시지) 테스트 대상 객체가 null 이 아닌지를 테스트
  • assertThrows() : (발생이 기대되는 예외 클래스, 람다 표현식 : 테스트 대상 메서드) : 기대하는 예외가 발생하는지를 테스트
    NullpointerException 클래스가 상속하고 있는, RuntimeException 클래스와 RuntimeException 클래스를 다시 상속하고 있는 Exception 클래스를 첫 파라미터로 적어주어도, 동일하게 작동한다.
    람다표현식은 JUnit에서 지원하는 Executable 함수형 인터페이스. void execute() throws Throwable; 메서드 하나만 정의되어 있으며 리턴값이 없는 Consumer 함수형 인터페이스이다.

- 테스트 케이스 실행하기

  • (1) : 클래스 내 전체 테스트 케이스 실행
  • (2) : 해당 테이스 케이스만 실행

- 성공 시

- 실패 시


*테스트 실행 전, 전처리 방법

- @BeforeEach

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class BeforeEach1Test {

    @BeforeEach
    public void init() {
        System.out.println("Pre-processing before each test case");
    }

    @DisplayName("@BeforeEach Test1")
    @Test
    public void beforeEachTest() {

    }

    @DisplayName("@BeforeEach Test2")
    @Test
    public void beforeEachTest2() {

    }
}
  • 각 테스트 메서드 마다, 실행하기 전에 실행되는 메서드
  • 테스트 수행 전, 초기화 작업에 사용된다.

- 출력 결과

Pre-processing before each test case
Pre-processing before each test case

 

- @BeforeAll

public class BeforeAllTest {
    private static Map<String, String> map;

    @BeforeAll
    public static void initAll() {
        map = new HashMap<>();
        map.put("BTC", "Bitcoin");
        map.put("ETH", "Ethereum");
        map.put("ADA", "ADA");
        map.put("POT", "Polkadot");
        map.put("XRP", "Ripple");

        System.out.println("initialize Crypto Currency map");
    }

    @DisplayName("Test case 1")
    @Test
    public void beforeEachTest() {
        assertDoesNotThrow(() -> getCryptoCurrency("XRP"));
    }

    @DisplayName("Test case 2")
    @Test
    public void beforeEachTest2() {
        assertDoesNotThrow(() -> getCryptoCurrency("ADA"));
    }

    private String getCryptoCurrency(String unit) {
        return map.get(unit).toUpperCase();
    }
}
  • 전체 테스트 케이스가 실행되기 전에 딱 한번만 실행되는 메서드
  • 초기화를 한번만 하고싶을 때 사용한다.

- 출력 결과

initialize Crypto Currency map

*Assumption

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

public class AssumptionTest {
    @DisplayName("Assumption Test")
    @Test
    public void assumptionTest() {
        assumeTrue(System.getProperty("os.name").startsWith("Windows"));
 //       assumeTrue(System.getProperty("os.name").startsWith("Linux")); 
        System.out.println("execute?");
        assertTrue(processOnlyWindowsTask());
    }

    private boolean processOnlyWindowsTask() {
        return true;
    }
}
  • assumeTrue() : 파라미터 입력값이 true이면 아래 다른 로직들이 실행되고, false이면 실행되지 않는다.
  • 여기서는 PC의 운영체제가 Windows일 때만 실행되게 하였다.

*특정 테스트 비활성화하기

- @Disabled

@Disabled("이슈 #003 가 해결될 때 까지 비활성화")
public class AssumptionTest {
    @DisplayName("Assumption Test")
    @Test
 //   @Disabled("#42 버그가 해결될 때 까지 비활성화")
    public void assumptionTest() {
        assumeTrue(System.getProperty("os.name").startsWith("Windows"));
 //       assumeTrue(System.getProperty("os.name").startsWith("Linux")); 
        System.out.println("execute?");
        assertTrue(processOnlyWindowsTask());
    }
}
  • 클래스, 메서드에 선언 가능하며, JUnit에서는 위 예처럼 비활성화 이유에 대해 명시하기를 권장하고 있다.

'Testing skills' 카테고리의 다른 글

Mockito와 Mocking  (0) 2022.08.19
Comments