Develop/Java & Spring

[Spring Boot] 게시판 프로젝트 외전 #1 JUnit과 Mockito를 이용한 테스트 - 이론

jjh0119 2025. 3. 25. 18:42

게시판 프로젝트를 1차적으로 마무리하고 나서 계속 버전업을 시키려고 어떤 걸 해야할까 생각을 하던 중 정처기 공부를 하며 알게 된 Testing을 프로젝트 초기에 적용시켜봐야겠다 생각하고 공부를 시작했다.
테스트 코드를 작성하는 건 처음이라 모르는 것 투성이인 상태였고 공부를 위해 기초적인 개념과 용어부터 정리해봤다.

#1. 단위 테스트(Unit Test)

1.단위 테스트란?

  • 소프트웨어 개발에서 개별적인 코드 단위를 테스트하는 것을 의미
  • 코드의 작은 부분을 격리시켜 하나의 모듈을 만들어 독립적으로 테스트함으로써 코드의 정확성과 신뢰성을 검증
  • 하나의 모듈이란 각 계층에서 하나의 기능 또는 메소드로 이해할 수 있으며 이 기능이 올바르게 동작하는지 독립적으로 테스트하는 것
  • 자동화가 되고 반복 가능하며 버그를 빠르게 찾아내고 수정하는 데 도움이 됨
  • 코드 변경 시 기존 기능에 영향을 주지 않고 코드의 동작을 확인하는 데 유용

2.단위 테스트의 필요성

  • 일반적으로 테스트 코드를 작성한다고 하면 거의 단위 테스트를 의미한다.
  • 통합 테스트는 실제 여러 컴포넌트들 간의 상호작용을 테스트하기 때문에 모든 컴포넌트들이 구동된 상태에서 테스트를 하게 되므로, 캐시나 데이터베이스 등 다른 컴포넌트들과 실제 연결을 해야하고 어플리케이션을 구성하는 컴포넌트들이 많아질수록 테스트를 위한 시간이 커진다.
  • 단위 테스트는 테스트하고자 하는 부분만 독립적으로 테스트를 하기 때문에 해당 단위를 유지보수 또는 리팩토링 하더라도 빠르게 문제여부를 확인 할 수 있다.

#2. JUnit과 Mockito

1. JUnit5

  • java 언어에서 독립된 단위 테스트를 지원해주는 프레임워크
  • JUnit Platform, Jupiter, Vintage 모듈이 결합된 형태

2. Mockito

  • 단위 테스트를 위해 모의 객체(Mock Object)를 생성하고 관리하는 데 사용되는 오픈소스 프레임워크
  • 이를 사용하면 실제 객체의 동작을 모방하는 모의 객체를 생성하여 코드의 '특정 부분을 격리'시키고 테스트하기 쉽게 만들어 줌

3. Mockito를 이용한 테스트 목적

  • Mockito를 사용하여 모의객체와 함께 서비스를 호출하여 비즈니스 로직이 올바르게 처리가 되는지 확인하기 위해 테스트를 수행
  • 이러한 테스트 과정을 통해 서비스의 비즈니스 로직에 대해 검증하고 예외상황에 대해 처리를 확인함

4. JUnit5 + Mockito 흐름


이 그림에서 위의 흐름이 JUnit만을 사용했을 때의 테스트 흐름이라면 아래가 Mocktito를 같이 활용했을 때의 테스트 케이스의 흐름이다.
즉 @Test를 수행하는 TestMethod()에서 서비스 호출을 위해 getCodeList() 함수를 호출하지만 DB에서 데이터를 조회해 오는것이 아닌 직접적인 DB호출 없이 임시적으로 DB의 역할을 할 수 있게 만들어진 Mock Object와 상호작용하며 테스트를 진행하게 된다.


#3. 단위 테스트 작성

보통 테스트를 위한 라이브러리로 JUnit과 AssertJ의 조합을 사용하는데 여기에 더해 앞서 설명한 Mockito까지 활용해 단위 테스트 코드를 작성해보려고 한다.

1. Given-When-Then 패턴

  • 테스트 케이스를 더 가독성 있고 유지보수하기 쉽도록 구조화하는 방법을 의미
  • 이 패턴을 따르면 테스트 케이스가 더 구체적이고 이해하기 쉬워지며 각각의 단계를 분리하여 각 테스트 부분이 어떤 역할을 담당하는지 명확해 짐

  • Given
    • 테스트 시나리오에서 사전 조건을 설정하는 부분
    • 즉, 객체의 초기 상태나 호출된 메서드의 입력값을 설정하는 단계
    • 예를 들어 Given 단계에서 모의 객체의 특정 메서드가 호출되었을 때 어떤 값을 반환하도록 설정할 수 있음
  • When
    • 테스트할 메서드를 호출하는 부분
    • 이 부분에서는 실제로 테스트 대상 메서드를 호출하여 원하는 동작을 검증
  • Then
    • 테스트의 결과를 검증하는 부분
    • 예상되는 결과를 검증하고, 모의 객체의 메서드가 예상대로 호출되었는지 확인할 수 있음

2. Given-When-Then 패턴 예시

result 값과 expectedValue 값이 일치하는지를 검증하고 mockObject의 someMethod()가 예상대로 호출되었는지를 확인하기 위한 예시

  • Given : 사전 조건
    • mockObject의 someMethod() 메서드가 호출되었을 때 expectedValue를 반환하도록 설정
  • When : 동작을 검증
    • testedObject의 testedMethod()를 호출하여 실제로 테스트 대상 메서드를 실행
  • Then : 테스트 결과 검증
    • result가 expectedValue와 일치하는지를 검증하고, mockObject의 someMethod()가 예상대로 호출되었는지를 확인합니다.
// Given
Mockito.when(mockObject.someMethod()).thenReturn(expectedValue);

// When
Object result = testedObject.testedMethod();

// Then
assertEquals(expectedValue, result);
Mockito.verify(mockObject).someMethod();