본문 바로가기
Spring/JUnit

JUnit

by step 1 2021. 6. 27.
반응형

TDD(Test-Driven Development)

테스트 주도 개발에서 사용하지만, 코드의 유지 보수 및 운영 환경에서의 에러를 미리 방지 하기 위해서 단위 별로 검증하는 테스트 프레임워크

 

단위 테스트

작성한 코드가 기대하는 대로 동작을 하는지 검증 하는 절차

 

JUnit

Java기반의 단위 테스트를 위한 프레임워크

Annotation 기반으로 테스트를 지원하며, Assert를 통하여, (예상, 실제)를 통해 검증

 

 

실습 환경: Gradle 자바 프로젝트로 진행

해당 dependency, test가 존재하는지 확인

 

테스트를 진행하기 위한 계산 코드 작성

ICalculator 인터페이스 생성

public interface ICalculator {

    int sum(int x, int y);
    int minus(int x, int y);
}

원화 계산을 하기위한 KrwCalculator 클래스 생성

public class KrwCalculator implements ICalculator{

    private int price = 1;

    @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;
    }
}

달러 계산을 하기위한 DollarCalculator 클래스 생성

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;
    }
}

 

환율 값을 가져올 MarketApi 클래스 생성

public class MarketApi {

    public int connect(){
        return 1100;
    }
}

 

원화 클래스와 달러 클래스를 주입받기 위한 Calculator 클래스 선언

public class Calculator {

    private ICalculator iCalculator;

    public Calculator(ICalculator iCalculator){
        this.iCalculator = iCalculator;
    }

    public int sum(int x, int y){
        return this.iCalculator.sum(x,y);
    }

    public  int minus(int x, int y){
        return iCalculator.minus(x, y);
    }
}

 

테스트 코드 작성 (어노테이션 이용)

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

// Mock 어노테이션을 사용하기 위해 선언
@ExtendWith(MockitoExtension.class)
public class DollarCalculatorTest {

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

    // 테스트를 진행하려는 클래스 지정
    @Mock
    public MarketApi marketApi;

    // 원하는 클래스에 메소드가 동작할때 사용자 임의로 데이터를 설정할 수 있다.
    @BeforeEach
    public void init(){
        Mockito.lenient().when(marketApi.connect()).thenReturn(3000);
    }

    @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("예상하는 데이터", "실제 동작하는 데이터")
        Assertions.assertEquals(22000, calculator.sum(10,10));
        Assertions.assertEquals(0, calculator.minus(10,10));
    }

    // Mock 어노테이션을 이용한 테스트 진행 함수
    @Test
    public void MockTest(){

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


        Calculator calculator = new Calculator(dollarCalculator);
        Calculator calculatorK = new Calculator(new KrwCalculator());

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

        // Assertions.assertEquals("예상하는 데이터", "실제 동작하는 데이터")
        Assertions.assertEquals(60000, calculator.sum(10,10));
        Assertions.assertEquals(0, calculator.minus(10,10));

        Assertions.assertEquals(20, calculatorK.sum(10,10));
        Assertions.assertEquals(0, calculatorK.minus(10,10));
    }
}

예상한 데이터와 실제 데이터가 다를 경우 콘솔 화면

 

데이터가 일치할 경우 콘솔 화면

사용한 어노테이션

@ExtendWith(MockitoExtension.class) Mock 어노테이션을 사용하기 위해 선언
@Test 테스트를 진행할 메소드에 선언
@Mock 테스트를 진행할 때 사용할 클래스에 선언
@BeforeEach 원하는 클래스에 메소드가 동작할때 사용자 임의로 데이터를 설정할 수 있다.

Mock 어노테이션을 사용하기위해서 디펜던시를 추가로 등록해주어야 한다.

MvnRepository에서 Mockito 검색

https://mvnrepository.com/artifact/org.mockito/mockito-core/3.11.2

https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter/3.11.2

 

참고 사이트

https://javacan.tistory.com/entry/MocktestUsingMockito

 

Mockito를 이용한 MockTest

필자는 원하는 기능을 제공하는 Mock 라이브러리를 찾지 못해 (또는 완전히 학습하지 못해?) 필요한 기능을 제공하는 간단한 라이브러리를 직접 만들어서 사용한 적도 있다. 그런데, 매우 맘에

javacan.tistory.com

 

반응형