2024. 5. 14. 16:16ㆍTechnology/Others

3개월 전에 Test Code 100개를 겨우 넘기고 자랑스럽게 남긴 링띤 글.
지금은 두 명의 든든한 새 백엔드 팀원 Does, Kerry 도 합류하고 Test Code도 500개에 도달했다.
여기까지 오는 과정에서 참 많은 고민거리가 있었고, 재밌는 이슈들도 많았는데.
그중 가장 짜릿하다고 느낀 DIP 적용과 그로 인한 Test Code 이슈 해결 과정을 정리해보려 한다.

현재 우모(Umoh)의 모듈 구조를 간단하게 표현하면 비즈니스 도메인을 담은 common 모듈을 중심으로, batch/integration/core* 모듈이 있다. 그렇기 때문에 common 모듈은 integration 모듈을 알지 못한다. 그리고 integration에서 EmailSender가 구현되어 있다.
*core: 모든 모듈에서 공통으로 사용하는 코드를 넣는 모듈로 정의했다.
이 상태에서 common이 비즈니스 로직 구현을 위해 EmailSender를 써야 하는 상황이 생겼다.
common은 integration을 알면 안 되는데..! 오또카지?

구현체는 integration module에 두고, sender interface를 common module에 위치시키는 방법을 선택했다. 적용한 이 방법을 설명하는 개념이 DIP(Dependency Inversion Principle)이다.
DIP(Dependency Inversion Principle): 의존성 역전 원칙
1. 하위 모듈에 의존하지 않는 것
2. 변화하지 않는 것에 의존하는 것
DIP는 이 2가지만 지키면 되는데, 일단 변화하지 않는 코드 하면 어떤 것이 떠오르는가? 바로 Interface이다. 원래는 아래처럼 MemberService가 구체적인 ProductionMemberEmailSender를 직접 쓰고 있다고 가정해 보자.

이제 변화하지 않는 것에 의존하도록 Interface를 만들자.
EmailSender에서 member에게 send 한다는 변하지 않는 목적을 명시해 둔 Interface를 만들고 사용한다. 구체적인 구현은 여전히 ProductionMemberEmailSender가 담당하는 것이다.
fun interface MemberEmailSender {
fun send(member: Member): Boolean
}

이제 이걸 common module은 자유롭게 사용하면 되는데, 하위모듈에 의존하고 있는 점이 여전히 DIP 원칙에 부합하지 않는다.
interface를 common module로 옮겨버리면?

integration이라는 하위 모듈은 상위 모듈에 의존하는 형태가 되었다. 또한 MemberService는 변하지 않는 코드에 의존한다.
이때 발생할 수 있는 이슈는 테스트 코드인데, common module 테스트 코드에서 MemberEmailSender의 세부 구현이 없다고 징징거릴 것이다. 어차피 세부 구현에 대한 테스트는 integration module에서 이루어지면 되므로, common module에서는 TestConfiguration에 항상 성공하는 MemberEmailSender를 주입시켜 주면 된다.
@SpringBootApplication
class CommonTestConfiguration{
@TestConfiguration
class CommonTestConfiguration {
@Bean
fun memberEmailSender() = MemberEmailSender { _ -> true }
}
}
사실 api module의 seruciryConfig에 정의된 PasswordEncoder를 common에서 써야 할 때 처음 이 개념을 적용했다. 한 번 맞다이 뜨고 나니, 이번과 같은 EmailSender 같은 상황에서도 금방 적용해 볼 수 있었다.
common module에 구현해 버리고 모른 체할 수 있었던 상황에서도 최선의 선택인지 고민하고, 최선의 구현을 이루어낸 보람찬 이야기를 꼭 블로그에 남기고 싶었다. 그런 의미로 다음 이야기는 엉망진창 Test Data 정리 여정이 될 것 같다.
앞으로도 비즈니스 임팩트를 지키며, 최선의 선택으로 개발하는 모습을 꾸준히 유지하고 발전시키고 싶다.😋
'Technology > Others' 카테고리의 다른 글
T라 미숙해 (feat. 제네릭, 어디까지 써봤니?) - 2 (1) | 2024.09.08 |
---|---|
T라 미숙해 (feat. 제네릭, 어디까지 써봤니?) - 1 (3) | 2024.09.08 |
선배 Proxy 고려해서 equals 오버라이드 해주세요, 탕탕 후루후루~ (2) | 2024.07.26 |
Controller 먼저? Domain 먼저? (0) | 2024.02.10 |
TDD - Test Scenario, Test Case, Test Code (0) | 2023.09.24 |