본문 바로가기

프로그래밍/JAVA

[Spring] Junit 테스트

728x90
반응형

Junit으로 우리가 만든 API가 정상적인지 테스트하는 코드를 알아볼 것이다

 

Junit으로 테스트를 하게 되면 서버를 작동시키고 Postman 이라던지 API 테스트 툴을 이용하지 않고도

 

우리가 원하는 URL을 호출하고 파라미터를 넘겨서 확인해 볼 수 있다

 

우선 테스트하기 위해 프로젝트를 하나 만들어 준다

 

JunitTest라는 프로젝트를 만들어 주는데 Maven으로 만들던 Gradle로 만들던 아무 상관없다

 

Dependencies는 간단하게 lombok과 spring web 만 추가해 주었다

 

그리고 controller를 만들어 주는데 간단하게 덧셈, 뺄셈을 해주는 API를 만들고 테스트를 해 보자

 

패키지와 파일은 이렇게 생성을 한 뒤 아래와 같이 소스를 작성한다

 

ApiController.java

package com.example.junittest.controller;

import com.example.junittest.Service.CalService;
import com.example.junittest.dto.Req;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class ApiController {

    private final CalService calService;

    @GetMapping("/sum")
    public int sum(@RequestParam int x, @RequestParam int y) {
        return calService.sum(x, y);
    }

    @PostMapping("/minus")
    public Req minus(@RequestBody Req req) {
        int result = calService.minus(req.getX(), req.getY());
        req.setResult(result);
        req.setResponse(new Req.Body());

        return req;
    }
}

Req.java

package com.example.junittest.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;

@Data
@AllArgsConstructor
@RequiredArgsConstructor
public class Req {

    private int x;
    private int y;
    private int result;

    private Body response;

    @Data
    @AllArgsConstructor
    @RequiredArgsConstructor
    public static class Body {
        private String resultCode = "OK";
    }
}

CalService.java

package com.example.junittest.Service;

import org.springframework.stereotype.Service;

@Service
public class CalService {

    public int sum(int x, int y) {
        return x + y;
    }

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

 

서버를 실행시키고 URL을 확인해 보면 정상적으로 작동이 되는 걸 확인할 수 있다

 

이제 우리는 서버를 실행시키지 않고 Junit으로 단위 테스트를 해볼 것이다

 

test 아래 controller 패키지를 만들고 ApiControllerTest라는 클래스를 하나 만든다

 

ApiControllerTest.java

package com.example.junittest.controller;

import com.example.junittest.Service.CalService;
import com.example.junittest.dto.Req;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

@WebMvcTest(ApiController.class)
@AutoConfigureWebMvc
@Import(CalService.class)
public class ApiControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void sumTest() throws Exception {

        mockMvc.perform(
                MockMvcRequestBuilders.get("http://localhost:8080/api/sum")
                .queryParam("x", "10")
                .queryParam("y", "10")
        ).andExpect(
                MockMvcResultMatchers.status().isOk()
        ).andExpect(
                MockMvcResultMatchers.content().string(("20"))
        ).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(
                MockMvcRequestBuilders.post("http://localhost:8080/api/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());
    }
}

테스트 코드를 위와 같이 작성 한 후 단위 테스트를 돌려 보면 정상적으로 실행이 된다

 

@WebMvcTest에 우리가 테스트할 컨트롤러 클래스를 등록해 준 뒤

@Import로 컨트롤러에서 주입받고 있는 클래스를 등록해 준다

 

그리고 MockMvc를 @Autowired 시켜 주면 테스트 준비는 끝이다

 

단위 테스트를 위해 sumTest 와 minusTest를 작성 해준 뒤 각각 get과 post로 URL을 호출해

 

파라미터를 10, 10 넘겨 주었다

 

우리가 원하는 값은 sum은 20이 나올 것이고

 

minus는 {"x":10, "y":10, "result":0, "response":{"resultCode":"OK"}} 의 JSON 형태의 값이 리턴될 것이다

 

mockMvc로 URL과 파라미터를 세팅 해준 뒤 넘겨준 파라미터에 맞게 원하는 값이 출력이 되는지를 

 

확인하는 코드이다

MockMvcResultMatchers.jsonPath("$.result"). value("0")
MockMvcResultMatchers.jsonPath("$.response.resultCode"). value("OK")

이 부분들은 post방식으로 호출했을 때 리턴 받은 JSON 값이 맞는지를 비교해 주는 코드인데

 

jsonPath에 result라는 값이 0인지 response에 resultCode 값이 OK 인지 확인하라는 뜻이다

 

에러를 확인해 보고 싶으면 CalService에서 sum과 minus에 연산기호를 바꿔 보면 에러를 확인할 수 있다

 

누군가와 협업을 한다거나 실수로 코드가 변경이 되었을 때 테스트를 돌려 에러를 확인해 보면 쉽게 찾을 수 있을 것이다

 

post와 get부분을 put과 delete로 바꾸면 동일하게 사용할 수 있다

 

MockMvc로 간단하게 URL호출 및 파라미터 전달, 전달받은 JSON객체의 값을 확인하는 방법들을 알아보았다

 

 

728x90
반응형