S3를 사용해서 프로필 이미지를 보관하고 있는데
단위테스트를 돌릴 땐 S3를 직접 쓰지 않는 방식으로 저장/삭제 테스트를 했다.
즉, 현재 구조가
이렇게 ProfileFacade가 있는데 여기서 우선 validate를 앞단에서 다 진행해준다.
그걸 통과한 애들만 s3에 저장되고, 이 s3정보가 db에 저장된다.
validation을 앞부분에 해서 s3 자원을 낭비하지 않도록 했다.
관련 내용은 Validation을 외부 리소스(S3)를 사용하기 전에 진행하자 여기에 정리해두었다.
그래서, 테스트를 할 때는 db관련 작업만 테스트하려고(s3자원 낭비를 막기위해서)
이렇게 profileImageService만을 테스트하게 됐다.
그런데, 이렇게 하니 문제가 생겼다.
클라이언트 분들이 api를 붙이는 과정에서 뭔가 잘 안된다.
그 이유를 보니 validation에서 계속 여러 케이스가 걸려버리는 문제가 생긴 것이다.
프로필 이미지를 업데이트하는 상황들을 모두 facade단에서 테스트를 안하니
일부 케이스가 validation에서 막혀서 500 에러가 뜨는 문제가 생겼다.
가령,
validation에서 이런 예외가 계속 발생한 것...!
Facade단을 테스트하지 않으니 use case들이 다 정확하게 작동하는지 테스트할 수가 없었다.
(Facade단은 주로 validation이 제대로 되는지만 테스트를 했다)
다만, 문제는 아마존의 S3는 저장 시 비용이 발생할 수 있다는 것이다.
이런 경우는 그냥 간단하게 Mock을 쓰면 된다.
지금은 s3에 사진이 잘 올라가는지가 중요한 게 아니라, s3 로직 앞단까지 잘 수행되는지가 중요하다.
여기에 더해서 validate로직을 따로 분리하기로 했다.
지금 validation 로직이 너무 복잡하기 때문이다... 이거말고도 뒤에 로직들이 더 있는데
이걸 엔티티 도메인 내부 메서드로 놓았는데, 비즈니스 로직이 복잡해짐에 따라 분리하는 게 더 좋을듯하다.
그래야 테스트하기도 편하니까. 지금 서비스, facade단에도 너무 많은 validation 로직이 범벅이다..
우선 validator를 하나 만들고 거기에 검증 로직을 모두 넣어두었다.
facade부분이 한결 슬림해졌는데, 그전에는 내가 만든 로직임에도 이해하려면 조금 시간이 걸렸다.
이렇게 모아두니
이렇게 공통된 것들은 따로 메서드로 분리할 수 있었다.
Localstack이라는 라이브러리도 있는 거 같은데
이건 aws 서비스들을 도커로 띄워서 하는 거 같다.
지금 단계에선 불필요하다.
Mock을 사용해서 간단하게 테스트하자.
@BeforeEach
void setUp() {
userGenerator.generateWithRole("fnel123", "123", "dd", "연호", TOP, HUNTER);
file = new MockMultipartFile(
"file",
"test.jpg",
"image/jpeg",
new byte[0] // 빈 파일
);
when(s3ImagesServiceV1.uploadImages(anyList())).thenReturn(
List.of(new SavedImage("test.jpg", true)));
verify(s3ImagesServiceV1).uploadImages(anyList()); //MOCK이 잘 호출됐는지
}
그리고, Mutlipart(사진파일)도 mock으로 만들어놓고, mock이 반환할 데이터도 미리 지정해둔다.
디버깅을 해보면 내가 지정해둔 데이터를 그대로 반환하는 걸 알 수 있다.
이제 이 mock을 활용해서 validation 테스트를 다 진행해볼 계획이다.