본문 바로가기

TIL

[JUnit으로 비즈니스 로직에 단위 테스트 적용하기]

728x90

핵심 포인트

  • JUnit의 기본 사용법을 이해할 수 있다.

JUnit은 java언어로 만들어진 애플리케이션을 테스트하기 위한 오픈 소스 테스트 프레임워크로서 사실상 Java의 표준 테스트 프레임워크라고도 한다. 

   assertThrows(NullPointerException.class, () -> getCryptoCurrency("XRP"));
    }

    private String getCryptoCurrency(String unit) {
        return CryptoCurrency.map.get(unit).toUpperCase();
    }

첫번째 파라미터에는 발생이 기대되는 예외 클라스를 입력, 두번째 파라미터인 람다 표현식에서는 테스트 대상 메서드를 호출, 두번째 파라미터엔 찾을수 없는 값이 있고 첫번째는 이미 없을껄 알고있기 때문에 발생이 기대되는 값으로 NullPointerException이올꺼라 예상했기 때문에 테스트 결과가 passed가 된다
NullPointException.class 대신 IllegalStateException.class을 쓰면 Error
nullPointException.class 대신 RuntimeException.class 또는 Exception.class는 passed
둘은 nullPointException.class >RuntimeException.class > Exception.class 이렇게 상속하고있음.

이처럼 assertThrows() 를 사용해서 예외를 테스트 하기 위해서는 예외 클래스의 상속 관계를 이해한 상태에서 테스트 실행 결과를 예상해야 된다는 사실을 기억하자

테스트 케이스 실행시, 예외가 발생한다고 전부 "failed"가 아니라 테스트 케이스 실행에서 예외가 발생한다 하더라도 예외가 발생한다라고 기대하는 순간(Expected) 예외가 발생하는 것은 "passed"가 되는것이다 >쉽게말해 내가 기대한값이 failed인데 failed가 나오면 pass인것이다.

 

Executable 함수형 인터페이스

assertThrows()의 두번째 파라미터인 람다 표현식은 JUnit에서 지원하는 Executable 함수형  인터페이스이다 
Executable 함수형 인터페이스는 void execute() throws Throwable; 메서드 하나만 정의되어 있으며 리턴값이 없다
Java에서 지원하는 함수형 인터페이스 중에서 리턴값이 없는 Consumer에 해당된다고 보면된다.

 

테스트 케이스 실행 전, 전처리

테스트 케이스를 실행하기 전에 어떤 객체나 값에 대한 초기화 작업등의 전처리 과정을 해야할 경우가 많다. 이경우 JUnit에서 사용할 수 있는 애너테이션이 바로 @BeforeEach 와 @BeforeAll()이다.

  • @BeforeEach

    @BeforeEach 애너테이션을 추가한 메서드는 테스트 케이스가 각각 실행될 때 마다 테스트 케이스 실행 직전에 먼저 실행되어 초기화 작업등을 진행한다. 
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가 2번 실행하게된다 왜냐하면 @BeforeEach로 인해 테스트 케이스가 실행하기 직전에 init()이 실행되고 실행될때마다 Pre-processing before each test case를 반환하고 2개의 테스트케이스가있으므로,

즉 test1테스트 전에 init 메서드 실행 > test1 실행끝 > test2 테스트 전에 init 메서드 실행 > test2 실행끝 이러한 순으로 흘러간다.

 

  • @BeforeAll
    클래스 레벨에서 테스트 케이스를 한꺼번에 실행 시키면 테스트 케이스가 실행되기 전에 딱 한번만 초기화 작업을 하는 애너테이션이다.
    애너테이션을 추가한 메서드는 정적 메서드(static method)여야 한다

JUnit에서는 테스트 케이스 실행이 끝난 시점에 후처리 작업을 할 수 있는 @AfterEach, @AfterAll 같은 애너테이션도 지원한다

@BeforeEach , @BeforeAll 과 동작 방식은 같고, 호출되는 시점만 반대이다.

 

Assumption을 이용한 조건부 테스트

Assumption은 "~라고 가정하고"라는 표현을 쓸 때의 가정에 해당한다. JUnit5의 Assumption 기능을 사용하면 특정 환경에만 테스트 케이스가 실행되도록 할 수 있다.

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

    private boolean processOnlyWindowsTask() {
        return true;
    }
}
1)에서 assumTrue()메서드는 파라미터로 입력된 값이 true이면 나머지 로직들이 실행된다.

 

728x90

'TIL' 카테고리의 다른 글

[Spring MVC][Mockito]  (0) 2022.11.10
[Spring MVC][Slice Test]  (0) 2022.11.09
[Spring][Hamcrest]  (0) 2022.11.09
[Spring MVC][Testing]  (0) 2022.11.08
[Spring][JPA][EntityMapping][JPA 연관 관계]  (0) 2022.11.07