JUnit이란?

자바프로그래밍용 단위 테스트 프레임워크이다. Annotation가반으로 테스트를 지원한다.

 

코드에 잘못된 부분이 있을 때 각각의 객체를 확인하고 객체에 정의된 메서드를 하나씩 확인해 어떤 부분이 잘못된 것인지 찾는 것은 얼핏봐도 매우 비효율적이다. 이런 과정을 간략화하기 위해 테스트클래스를 작성하여 테스트를 진행한다. 이 때 JUnit을 사용하면 더욱 간단하게 테스트를 진행할 수 있다.

 

 

build.gradle의 dependencies에 다음과 같이 추가를 해주면 사용이 가능하다. 

 

public class DollarCalculator implements ICalculator{

    private int price = 1;
    private MarketApi marketApi;


    public DollarCalculator(MarketApi marketApi){
        this.marketApi = marketApi;
    }

    public void init(){
        this.price = marketApi.connect();
    }


    @Override
    public int sum(int x, int y) {
        x *= price;
        y *= price;
        return x + y;
    }

    @Override
    public int minus(int x, int y) {
        x *= price;
        y *= price;
        return x - y;
    }
}

위는 내가 작성한 간단한 계산기이다. 위의 계산기가 제대로 작동하는 방법을 알기 위해서 main메서드에 객체를 생성하고 각각의 파라미터를 넣어 제대로 작동하는지를 확인할 수 있으나 이는 매우 번거로울 수 있다. 특히 spring boot에서 테스트를 진행하거나 매우 복잡한 클래스를 사용할 때 오류가 발생한 점을 찾는 것은 꽤나 시간낭비일 것이다.

 

우리는 그래서 저기 보이는 test폴더의 DollarCalculatorTest를 활용할 것이다.

@ExtendWith(MockitoExtension.class)
public class DollarCalculatorTest {

    @Mock
    public MarketApi marketApi;

    @BeforeEach
    public void init(){
        Mockito.lenient().when(marketApi.connect()).thenReturn(3000);
    }

    @Test
    public void testHello(){
        System.out.println("hello");
    }

    @Test
    public void dollarTest(){

        MarketApi marketApi = new MarketApi();
        DollarCalculator dollarCalculator = new DollarCalculator(marketApi);
        dollarCalculator.init();

        Calculator calculator = new Calculator(dollarCalculator);

        System.out.println(calculator.sum(10, 10));

        Assertions.assertEquals(22000, calculator.sum(10, 10));

    }

    @Test
    public void mockTest(){
        DollarCalculator dollarCalculator = new DollarCalculator(marketApi);
        dollarCalculator.init();

        Calculator calculator = new Calculator(dollarCalculator);

        Assertions.assertEquals(60000, calculator.sum(10, 10));

    }


}

위에서 부터 하나씩 살펴보자. 우선 처음보는 Annotation이 나왔다.

 

Mock란 무엇일까?

실제 객체를 만들어서 사용하기에는 객체간의 의존성이 강하거나 만들기에 비용이나 시간이 너무 오래 걸리는 경우 테스트를 위한 가짜 객체를 만들어 사용하는 방법이다.

MarketApi객체를 Mocking해줌으로써 가상의 객체를 형성해준다.

 

test메서드가 실행될 때 다른 메서드를 호출하는 위치를 정해주는 Annotation이 몇가지 있다.

우선 @Test는 IDE로 직접 실행하는 test메서드이다.

 

@BeforeAll, @AfterAll : 클래스에 존재하는 모든 메서드를 실행한다고 할 때 각각 메서드가 실행되기 전, 메서드가 전부 실행된 후에 실행되는 단위들을 나타낸다.

 

@BeforeEach, @AfterEach : 각각의 Test메서드가 실행될 때 호출되는 메서드이다. 해당 Annotation이 달리면 각각 Test메서드가 실행되기 전, 후에 실행된다.

 

위의 테스트 코드를 보면 @BeforeEach가 다음의 메서드에서 쓰인다.

@BeforeEach
    public void init(){
        Mockito.lenient().when(marketApi.connect()).thenReturn(3000);
    }

 

lenient()는 현재 코드에 쓰이지 않는 스터빙을 했을 때 에러가 뜨지 않도록 제약을 느슨하게 해주는 역할을 한다. 그렇다면 stubbing을 무엇일까?

 

stubbing은 가짜(Dummy)객체를 하나 만드는 것과 같다. 좀 더 자세히는 Dummy객체에서 원하는 값을 미리 정해놓고 그것을 리턴하게 만드는 것이다. 위에 근거하여 when(marketApi.connect()).thenReturn(3000);이 의미하는 바는 다음과 같다. '만약 marketApi.connect()를 요청하는 경우 return값은 3000' 과 같은 말이다.

 

이제 여러 test메서드로 어떻게 코드를 테스트하는지 보도록 하자.

dollarTest메서드를 보면

@Test
    public void dollarTest(){

        MarketApi marketApi = new MarketApi();
        DollarCalculator dollarCalculator = new DollarCalculator(marketApi);
        dollarCalculator.init();

        Calculator calculator = new Calculator(dollarCalculator);

        System.out.println(calculator.sum(10, 10));

        Assertions.assertEquals(22000, calculator.sum(10, 10));

    }

제일 아래에 Assertions.assertEquals(22000, calculator.sum(10, 10));이 보일 것이다. 이것이 의미하는 바는 객체 22000과 calculator.sum(10, 10)이 같으면 테스트를 통과시키는 코드이다. if문을 JUnit을 사용하여 간단하게 변경할 수 있도록 한 것이다. 이렇게 함으로써 우리가 작성한 sum이라는 메서드가 정상적으로 작동하는지 알 수 있다.

'웹 개발 일기 > Spring' 카테고리의 다른 글

Swagger  (0) 2021.06.22
JUnit을 Spring에서 활용하여 테스트 진행하기  (0) 2021.06.22
Rest Template를 사용한 Server간의 연결  (0) 2021.06.18
Filter / Interceptor  (0) 2021.06.17
예외 처리  (0) 2021.06.15

+ Recent posts