본문 바로가기
  • Let's study
BackEnd/Java

[Java] 명언 게시판 - TDD 적용하기

by 코딩고수이고파 2026. 7. 23.

이번에는 이미 구현했던 명언 게시판을 TDD(Test Driven Development) 방식으로 다시 구현해보았다.

기능 구현 자체보다 테스트를 먼저 작성하고, 테스트를 통과시키는 방식으로 개발하는 과정에 집중하였다.

세부 코드는 각 커밋을 참고하면 된다.

AssertJ 추가

테스트 코드에서 검증을 편하게 하기 위해 AssertJ를 사용하였다.

build.gradle.kts

testImplementation("org.assertj:assertj-core:3.26.3")
 

AssertJ는 assertThat()을 이용하여 가독성 좋은 테스트 코드를 작성할 수 있다.

🔗  관련 커밋

TestUtil 작성

콘솔 프로그램은 입력과 출력이 콘솔에 의존하기 때문에 테스트하기가 어렵다.

이를 해결하기 위해 TestUtil을 만들어 테스트 환경을 구성하였다.

 

  • 문자열을 Scanner로 만들어 입력 대체 (genScanner)
  • 콘솔 출력을 ByteArrayOutputStream으로 변경 (setOutToByteArray)
  • 테스트 종료 후 원래 출력으로 복원 (clearSetOutToByteArray)

덕분에 실제 키보드 입력 없이 테스트를 수행할 수 있게 되었다.

🔗  관련 커밋

테스트를 먼저 작성

기능을 구현하기 전에 먼저 테스트를 작성하였다.

 

  • == 명언 앱 == 출력

을 먼저 테스트 코드로 작성한 뒤, 테스트를 통과하도록 실제 코드를 구현하였다.

TDD에서는 테스트가 요구사항 역할을 한다.

🔗  관련 커밋

AppTestRunner 도입

테스트마다 반복되는 실행 코드를 하나로 묶어 테스트를 간결하게 만들었다.

🔗  관련 커밋

기능 구현

이후에는 기존 명언 게시판과 동일한 순서로 기능을 구현하였다.

 

  • 등록
  • 등록 번호 출력
  • 번호 자동 증가
  • 목록 조회

각 단계마다 테스트를 먼저 작성하고 테스트가 통과하도록 구현하였다.

🔗  관련 커밋

레이어드 아키텍처 적용

Controller, Service, Repository로 역할을 분리하여 책임을 명확하게 나누었다.

🔗  관련 커밋

Controller별 테스트 분리

레이어를 분리하면서 테스트도 함께 분리하였다.

 

  • WiseSayingControllerTest
  • SystemControllerTest

각 Controller를 독립적으로 테스트할 수 있게 되어 테스트 범위를 명확하게 구분할 수 있다.

🔗  관련 커밋

패키지 구조 리팩토링

클래스가 많아지면서 패키지 구조도 함께 정리하였다.

역할별로 패키지를 분리하면 필요한 클래스를 찾기 쉽고 프로젝트 구조를 이해하기도 편해진다.

🔗  관련 커밋

AppContext 도입

마지막으로 AppContext를 도입하였다.

객체를 한곳에서 생성하고 관리하도록 변경하여 Controller와 Service가 직접 객체를 생성하지 않도록 만들었다.

또한 개발 환경이나 테스트 환경에 따라 서로 다른 객체를 사용할 수 있는 기반을 마련하였다.

🔗  관련 커밋

댓글