포스트

테스트 때문에 엔티티에 setter를 추가하면 안 되는 이유

테스트 때문에 엔티티에 setter를 추가하면 안 되는 이유

결론부터 말하면

  • 엔티티에 setTempHoldExpiresAt()을 테스트 때문에 추가하는 건 비추천
  • Repository 레벨에서 “테스트 전용 만료 조작”을 제공하는 게 정석

지금 구조에서는 오히려
setter가 없는 것이 설계적으로 올바른 상태다.


setTempHoldExpiresAt()이 없는 게 맞는가?

1️⃣ Reservation은 “상태 전이 규칙”을 가진 도메인이다

Reservation은 단순한 데이터 객체가 아니다.
명확한 상태 전이 규칙(State Transition) 을 가진 도메인 엔티티다.

예를 들면:

  • TEMP_HOLD → CONFIRMED
  • TEMP_HOLD → EXPIRED

여기서 중요한 점은,

tempHoldExpiresAt
상태 전이의 결과이지,
외부에서 마음대로 수정할 수 있는 값이 아니라는 것
이다.

즉, 만료 시각은
“임시 배정 상태에 진입했을 때 계산되어 설정되는 값”이며
도메인 규칙의 일부다.

만약 엔티티에 이런 setter가 생긴다면:

1
reservation.setTempHoldExpiresAt(...)

이는 곧,

  • 상태 전이를 거치지 않고
  • 도메인 규칙을 우회하여
  • 내부 상태를 직접 조작할 수 있는 통로를 여는 것과 같다 👉 도메인 캡슐화가 깨지는 순간이다.

2️⃣ 테스트 편의를 위해 도메인을 훼손하면 안 된다

테스트 때문에 setter를 추가하는 순간, 사실상 이런 선택을 한 것과 다르지 않다.

  • 도메인 캡슐화 포기
  • 상태 전이 규칙 무력화
  • “테스트 편의성 > 설계 안정성” 우선

이건 좋은 테스트가 아니다.

좋은 테스트는 설계를 바꾸지 않는다. 나쁜 테스트는 설계를 망가뜨린다.

더 큰 문제는 이것이다.

  • 이 setter는 실서비스 코드에도 그대로 남는다
  • 누군가 실수로, 혹은 급한 수정으로 사용해버릴 수 있다
  • 그 순간 도메인의 불변 조건은 무너진다

테스트를 위해 추가한 코드가 운영 리스크로 돌아오는 전형적인 패턴이다.


정석적인 해결 방법 (추천)

✅ Repository 레벨에서 “테스트 전용 만료 조작”을 제공한다

도메인에는 손대지 않고, 영속성 계층에서만 테스트를 위한 조작을 허용하는 방식이다.

예를 들면 다음과 같다.

1
2
3
4
5
6
7
8
public interface ReservationRepositoryPort {

    void forceExpire(
        UUID reservationId,
        LocalDateTime expiredAt
    );

}

이 메서드는 다음 성격을 가진다.

  • 테스트 전용
  • 상태 전이 규칙을 대체하지 않음
  • 단순히 DB 상태를 조작하여 시간 경과를 시뮬레이션

이 방식의 장점은 명확하다

  • ✔ 엔티티 불변성 유지
  • ✔ 도메인 규칙 보호
  • ✔ 테스트에서만 시간 조작 가능
  • ✔ 실서비스 로직과 명확히 분리

도메인은 여전히 이렇게 말할 수 있다.

“나는 내 규칙대로만 상태가 바뀐다.”


왜 Repository 레벨이 적절한가?

이 선택의 핵심은 책임 분리다.

  • 도메인
    • 상태 전이 규칙을 지킨다
    • 외부 조작을 허용하지 않는다
  • Repository
    • 상태를 어떻게 저장하고 조회할지 책임진다
    • 테스트에서는 현실적으로 필요한 “시간 이동”을 시뮬레이션한다

테스트에서 시간 조작이 필요한 건 현실이다. 하지만 그 책임을 도메인에 넘기는 순간, 설계는 오염된다.

즉,

도메인은 규칙을 지키고 Repository는 현실을 시뮬레이션한다

이 역할 분리가 핵심이다.


정리

  • setTempHoldExpiresAt()이 없는 것은 설계적으로 정상이다
  • 테스트 때문에 엔티티에 setter를 추가하는 것은 안티 패턴이다
  • 테스트 전용 상태 조작은 Repository 레벨에서 해결하는 게 정석이다

결과적으로:

  • 도메인은 깨끗해지고
  • 테스트는 현실적이며
  • 구조는 오래 버틴다

한 줄 요약

테스트를 위해 도메인을 망가뜨리지 말자. 설계를 지키는 테스트가 결국 가장 강한 테스트다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.