
안녕하세요 ╰(°▽°)╯
오늘은 앞으로 진행할 프로젝트에서 중요한 과정 중 하나인 테스트 코드를 작성해보겠습니다.
제가 한 달 전쯤, 정보처리기사 필기 공부를 하면서 애플리케이션 테스트의 종류와 개념에 대해 정리한 글이 있는데, 자세한 내용이 궁금하시다면 해당 포스트를 참고해주세요 👍
먼저, 테스트 코드를 왜 작성해야 할까요?
제가 가장 큰 이유라고 생각하고, 가장 크게 체감하는 것은 바로 빠른 피드백입니다.
단위 테스트에 대해 배우기 전에 저는 이런 방식으로 개발을 진행했습니다.
여기서 2번~5번은 코드를 수정할 때마다 반복해야 하기 때문에, 굉장히 번거로웠습니다. 😂
하지만 테스트 코드를 작성하면 이런 문제가 해결되므로 굳이 직접 프로그램을 재시작 할 필요가 없어지게 되는 것이죠..!😉
테스트 코드 작성을 도와주는 여러 프레임워크들이 있습니다.
가장 대중적인 테스트 프레임워크로는 xUnit이 있는데 이는 개발환경에 따라 Unit 테스트를 도와주는 도구라고 생각하면 됩니다.
대표적인 xUnit 프레임워크들은 다음과 같습니다.
이 중에서 저는 자바용인 JUnit을 사용할 것입니다.🙌
지난 포스트에서 프로젝트 환경을 구축했었는데, 메인 클래스를 아직 안만들었죠?
우선 메인 클래스부터 이렇게 만들어 주겠습니다.
package com.b1uesoda.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication으로 인해 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성을 모두 자동으로 설정해줍니다.
특히나 이 어노테이션이 있는 위치부터 설정을 읽어가기 때문에 이 클래스(메인 클래스)는 항상 프로젝트의 최상단에 위치해야만 합니다.
그리고 main 메소드에서 실행하는 저 SpringApplication.run으로 인해 내장 WAS(Web Application Server)가 실행되는 과정을 거칩니다. 여기서 내장 WAS란 별도로 외부에 WAS를 두지 않고 애플리케이션을 실행할 때 내부에서 WAS를 실행하는 것을 말합니다.
그럼 이제 테스트를 위한 Controller를 만들어 볼까요?
저는 web이라는 패키지를 만들어 HelloController라는 이름의 클래스를 만들고 간단한 API를 만들었습니다.

package com.b1uesoda.springboot.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
여기서 @RestController는 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어주는 역할을 하는 어노테이션입니다.
작성한 코드가 제대로 작동하는지 테스트 코드로 검증을 해보겠습니다.
❗테스트 코드를 작성하기 전에, 저는 JUnit5 버전을 사용할 것이기 때문에,built.gradle에 dependency를 다음과 같이 설정했습니다!
dependencies {
testImplementation('org.junit.jupiter:junit-jupiter-api:5.7.0')
testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine:5.7.0')
testImplementation('org.junit.jupiter:junit-jupiter-params:5.7.0')
implementation('org.springframework.boot:spring-boot-starter-web')
testImplementation('org.springframework.boot:spring-boot-starter-test')
}

이렇게 test/java에 패키지를 똑같이 만들어 HelloControllerTest 클래스를 생성해주었습니다.
package com.b1uesoda.springboot.web;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void hello가_리턴된다() throws Exception {
String hello = "hello";
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(hello));
}
}
스프링 부트를 배워가는 단계이기 때문에 간단하게 코드를 설명하겠습니다.
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class)
@Controller, @ControllerAdvice 등을 사용할 수 있습니다.@Service, @Component, @Repository 등은 사용할 수 없습니다.@Autowired
private MockMvc mvc;
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(hello));
이렇게 코드를 모두 작성했으니, 한 번 실행해보겠습니다 👻


다음과 같이 테스트가 통과하는 것을 확인할 수 있습니다!
그럼 메인 메소드를 실행시켜 localhost:8080/hello로 접속해보겠습니다.

그랬더니 다음과 같이 문자열 hello가 잘 출력된 것을 확인할 수 있습니다.
오늘은 이렇게 견고한 소프트웨어를 만드는 중요한 요소 중 하나인 테스트 코드를 간단하게 만들어 보았습니다!
이러한 과정이 아직 익숙하지는 않지만, 나중에 발생할 번거로움에 대비해 꼭 필요한 단계라는 생각이 드네요😏
그럼 다음 포스트로 찾아뵙겠습니다. 읽어주셔서 감사합니다 :)
📚Reference
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - 이동욱
JUnit5 테스트 코드 작성하기