[Spring] JUnit

99winnmin·2022년 7월 15일
0

Spring

목록 보기
9/17

사전지식

  • TDD(Test-Driven Development) : 테스트 주도 개발에서 사용하지만, 코드의 유지 보수 및 운영 환경에서의 에러를 미리 방지하기 위해서 단위 별로 검증하는 테스트 프레임워크
  • 단위테스트 : 작성한 코드가 기대하는 대로 동작을 하는지 검증하는 절차

JUnit이란?

java기반의 단위 테스트를 위한 프레임워크
Annotation 기반으로 테스트를 지원하며, Assert를 통하여, 예상or실제를 통해 검증

  • JUnit 활용 코드
// Mockito 처리를 한다 : 특정한 객체에서 원하는 메소드가 호출이 되었을 때 원하는 결과값을 리턴한다??
@ExtendWith(MockitoExtension.class)
public class DollarCalculatorTest {

    @Mock // MarketApi 객체를 mock 처리한 것임
    public MarketApi marketApi;

    @BeforeEach
    public void init(){ // marketApi.connect()가 실행될 때 메서드의 리턴값이 아니라 내가 원하는 값을 리턴함
        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));
        Assertions.assertEquals(0,calculator.minus(10,10));
    }

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

        Calculator calculator = new Calculator(dollarCalculator);

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

        Assertions.assertEquals(60000, calculator.sum(10,10));
        Assertions.assertEquals(0,calculator.minus(10,10));
    }
}

위 방식은 spring에서 쓰는 방식은 아님 이제 spring에서 junit을 쓰는 방식을 보자
먼저, 짚고 넘어가야할 점은 테스트할 코드의 main디렉터리와 test디렉터리 하위 경로를 일치시켜줘야 한다는 점이다.

  • com.example.spring/main/JUnit 하위에 다음과 같이 작성했다면
  • 테스트 코드도 다음과 같이 경로를 맞춰주는 것이 좋다

다음은 component 하위의 객체들에 대한 테스트 코드와 controller에 대한 테스트 코드이다.

  • DollarCalculatorSpringTest.java : 위와 달리 spring 방식을 적용한 것
@SpringBootTest // 모든 bean이 자동 등록됨
public class DollarCalculatorSpringTest {

    @MockBean // spring은 bean으로 관리하기 때문에 mock이 아닌 mockbean을 사용
    private MarketApi marketApi;

    @Autowired
    private Calculator calculator;

    @Test
    public void dollarCalculatorTest(){
        Mockito.when(marketApi.connect()).thenReturn(3000);

        int sum = calculator.sum(10,10);
        int minus = calculator.minus(10,10);

        Assertions.assertEquals(60000,sum);
        Assertions.assertEquals(0, minus);
    }
}
  • CalculatorApiControllerTest.java : 브라우저에서 테스트하지 않아도 되는 테스트코드
@WebMvcTest(CalculatorApiController.class) // @SpringBootTest와 달리 web에 필요한 것만 로딩하기 때문에 자원소비가 덜함
@AutoConfigureWebMvc
@Import({Calculator.class, DollarCalculator.class})// 필요한 객체 주입
public class CalculatorApiControllerTest {

    @MockBean
    private MarketApi marketApi;

    @Autowired
    private MockMvc mockMvc; // Mvc를 mock으로 테스트하겠다는 것

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

    @Test
    public void sumTest() throws Exception { // 브라우저를 열지 않아도 테스트 가능!
        // http://localhost:9090/junit/sum
        mockMvc.perform(// GET 방식일때
                MockMvcRequestBuilders.get("http://localhost:9090/junit/sum")
                        .queryParam("x","10")
                        .queryParam("y","10")
        ).andExpect(
                MockMvcResultMatchers.status().isOk()
        ).andExpect(
                MockMvcResultMatchers.content().string("60000")
        ).andDo(MockMvcResultHandlers.print());
    }

    @Test
    public void minusTest() throws Exception {
        Req req = new Req();
        req.setX(10);
        req.setY(10);

        String json = new ObjectMapper().writeValueAsString(req);

        mockMvc.perform(// POST 방식일 때
               MockMvcRequestBuilders.post("http://localhost:9090/junit/minus")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(json)
        ).andExpect(
                MockMvcResultMatchers.status().isOk()
        ).andExpect(
                MockMvcResultMatchers.jsonPath("$.result").value("0")
        ).andExpect(
                MockMvcResultMatchers.jsonPath("$.response.resultCode").value("OK")
        ).andDo(MockMvcResultHandlers.print());
    }
}

Jacoco

java코드의 코드 커버리지를 체크하는 라이브러리
결과를 html,xml,csv로 확인이 가능하다.

STEP 1

build.gradle의 plugins에 id 'jacoco'을 추가한다.

STEP 2

Gradle에서 verification의 test를 먼저 실행시킨다.

그 후 index.html을 열어보면

다음과 같은 페이지를 볼 수 있다.

STEP 3

jacocoTestReport를 실행시킨다.

jacoco하위의 index.html을 열어본다.

다음과 같이 내가 작성한 코드에 대한 전체적인 테스트 비율을 알 수 있다.

출처 : 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online.

profile
功在不舍

0개의 댓글