오늘은 하루종일 테스트 코드만 두들겼어요.. 사실 직접 만드는거는 할 수 없어서 GPT를 채찍질 해가며 만들고, 이해하고, 더 쉽게 리팩토링 하는 방식으로 만들다가 한계를 느꼈답니다.😂
여러 관계가 얽힌 Service
의 테스트 코드는 Mock
을 활용하는데, 이 Mock
으로 생성한 객체(예를 들어 Store
의 이름) 내의 값들이 전부 Null
로 생성되어 작업 진행이 잘 되지 않았어요.
또한, Repository
에 저장한 객체를 불러와서 값을 비교하려고 했으나 계속 실패해 결국!! 튜터님께 찾아갔습니다.
제가 만들어낸 CRUD 중 Read를 제외한 다른 모든 로직은 void
를 반환하도록 설계했어요. 이렇게 하면 깔끔하고(?), 프론트에서 알아서 처리할 수 있을거라 생각했답니다.. 하지만 이 결과를 가지고 데이터를 확인해 테스트 코드를 만들고, 에러도 확인하기 용이하다구 하시더라구요. 아래에는 제가 받은 조언을 정리해놨습니다!
명확한 데이터 전달: ResponseDto
를 사용하면 클라이언트에 결과 데이터를 명확히 전달할 수 있어요. 단순 성공/실패 외에도 추가 정보를 포함할 수 있답니다.
확장성: 나중에 반환 데이터에 새로운 필드를 추가해야 할 경우, ResponseDto
를 사용하면 코드 변경 범위를 최소화할 수 있어요.
에러 처리 용이: 작업 결과와 에러 메시지를 함께 반환할 수 있어서 클라이언트가 오류를 더 쉽게 처리할 수 있어요.
일관된 API 설계: 모든 서비스 레이어가 동일한 형식(ResponseDto
)으로 데이터를 반환하면 코드의 일관성이 높아지고 유지보수가 쉬워져요.
테스트 편의성: 반환 값을 테스트하기 쉬워져서 단위 테스트 작성과 유지보수가 편해져요.
조언을 듣고 CRUD 중 Delete를 제외한 로직은 ResponseDto
에 담아서 반환했지만 Delete는 어쩔 수 없이 void
를 사용했어요. 근데 이 void
를 반환하면 Repository
에서 값을 직접 가져올 수 없기 때문에 isEqualTo
를 사용하지 못해요. 이때 사용하는 것이 verify
입니다!
void로 반환하는 메서드 검증: void
를 반환하는 메서드는 결과 값을 직접 확인할 수 없으니, junit
의 verify
를 사용해서 검증해요.
행위 기반 검증: verify
를 사용하면 메서드가 특정 조건에서 호출되었는지 확인할 수 있어요.
@Test
void testVoidMethod() {
// given
SomeService someService = mock(SomeService.class);
// when
someService.doSomething();
// then
verify(someService, times(1)).doSomething();
}