• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

FakeRepository 만들 때 Join 테이블하는 경우 질문드립니다.

23.10.12 14:35 작성 조회수 374

1

  • 서비스 테스트 시 Repository 상속해서 FakeRepository를 생성자 주입을 통해 진행한다는 내용에 대해서는 이해하고 실습해 보았습니다.

  • 그런데 만약 Repository 메서드 중 JPA의 on 절을 이용한 join을 사용해 데이터를 가져오는 경우 FakeRepository의 내부 구현이 궁금합니다

  • 내부에 Id와 List를 통해 해당 엔티티에 대한 정보를 저장할 수 있지만, Join을 하는 경우 외부 테이블의 정보가 필요하기 때문에 이를 Fake하고 싶을 때는 어떻게 해결할 수 있는지 알려주시면 감사하겠습니다.

답변 2

·

답변을 작성해보세요.

1

안녕하세요. 근래에 책을 집필할 기회가 생겨 그쪽에 힘을 실어주다 보니 다른 일에 신경 쓰지 못했습니다. 답변이 늦어 죄송합니다. 다만 해당 강의는 공식적으로 질의응답을 제공하지 않는 강의였다는 점을 이유로 늦어진 부분에 대해 양해 부탁드립니다.

우선 Join을 통해 데이터를 불러오는 예시부터 보여드리겠습니다. ‘게시물 댓글’이라는 관계가 있을 때 댓글에는 postId가 적혀있고, 게시물을 불러올 때 댓글도 같이 불러오고 싶다고 가정합시다. 이때 Fake는 아래와 같이 만들 수 있습니다.

public class FakePostWithCommentRepository implements PostWithCommentRepository {
 
    private final FakePostRepository fakePostRepository;
    private final FakeCommentRepository fakeCommentRepository;

    public FakePostWithCommentRepository(
            FakePostRepository fakePostRepository,
            FakeCommentRepository fakeCommentRepository) {
        this.fakePostRepository = fakePostRepository;
        this.fakeCommentRepository = fakeCommentRepository;
    }
    
    @Override
    public Optional<PostWithComment> findById(long id) {
        return fakePostRepository.findById()
            .map(post -> PostWithComment.builder()
                .post(post)
                .comments(fakeCommentRepository.findByPostId())
                .build());
    }
}

코드 a

Join이 사용되는 Fake를 만들 때 Join에 필요한 데이터 소스를 갖고 있는 Repository를 생성자 주입받고 이를 활용하도록 하는 겁니다.

아무튼 Join을 거는 상황 자체는 위와 같이 해결할 수 있는데, 문의해 주신 질문을 읽었을 때 질문자님이 궁금한 것은 단순히 Join을 거는 상황에서 데이터를 어떻게 불러오는지가 궁금한 것 같지 않습니다.

오히려 그것보다 Fake가 있는 경우 데이터 정합성을 어떻게 보장할 수 있는지가 궁금한 것 같은데요. 예를 들면 예제 프로젝트에서 사용했던 아래 두 Fake Repository를 한 번 다시 보고 와봅시다.

FakePostRepository에서 Writer는 FakeUserRepository의 data에 있는 값이 아닙니다. 그래서 FakeUserRepository에서 사용자 정보를 변경하더라도 FakePostRepository에 있는 게시물에서 Writer정보도 같이 변경되는 것이 아닙니다. 그리고 이는 명백히 정합성이 깨진 상황입니다.

이런 경우 FakePostRepository가 FakeUserRepository를 [코드 a]와 마찬가지로 FakePostRepository가 FakeUserRepository를 갖고 있게 함으로써 문제를 해결할 수 있습니다. 다만 굉장히 많은 것을 고려해야 하고 Fake의 내부 코드 자체가 굉장히 지저분해지기 시작할 겁니다.

그래서 결국 RDB를 사용하고 있는 상황에서 테이블에 연관 관계가 복잡하게 얽혀있는 경우 완전한 Fake를 만들어 이를 대체하도록 하는 것은 무척이나 어려운 일입니다. 사실상 RDB의 모든 기능을 Fake로 완전히 대체하겠다는 목표도 달성할 수 없는 목표에 가깝고요.

본 강의의 목표는 테스트 프레임워크나 h2 사용 자체를 하지 말자는 것을 지향하는 것이 아닙니다. 적어도 쓸 땐 쓰더라도 테스트 프레임워크가 어떤 일을 도와주고 있고, h2 없이도 어떻게 테스트를 만들 수 있는지를 알려드리는 것을 목표로 하고 있습니다. 그러므로 상황이 정말로 복잡하다면 h2나 stub을 활용해도 좋은 것 같습니다!

마지막으로 개인적으론 Fake를 만들기 쉬울 만큼 객체나 테이블 관계를 복잡하게 안 만들려 노력합니다.

답변이 도움 됐길 바랍니다.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.10.13

안녕하세요, 인프런 AI 인턴이에요. FakeRepository를 만들 때 Join을 사용하는 경우에 대해 질문이 있으셨군요. FakeRepository는 실제 데이터베이스와 연결되지 않는 가짜 레포지토리입니다. 따라서 Join과 같은 복잡한 데이터 조회는 구현하기 어려울 수 있습니다.

Join 연산을 하는 경우에는 외부 테이블의 정보가 필요하므로, 가짜로 생성한 FakeRepository에서 외부 테이블에 대한 정보를 구현하기 어려울 것입니다. 따라서 FakeRepository를 만들 때는 주로 단순한 데이터 조회나 CRUD 기능을 구현하고, Join을 사용하는 복잡한 조회의 경우에는 실제 Repository를 사용하거나 Mock 객체를 사용하여 테스트하시는 것이 좋습니다.

실제 Repository를 사용하는 경우에는 데이터베이스에 연결되기 때문에 Join과 같은 복잡한 조회도 가능합니다. Mock 객체를 사용하는 경우에는 테스트에서 필요한 데이터를 강제로 지정하여 원하는 결과를 받을 수 있습니다. Mock 객체를 사용하는 방법은 다양하게 있으니 필요한 경우에는 관련 라이브러리나 가이드를 참고하시면 도움이 될 것입니다.

조금 더 구체적인 문제나 예시를 알려주시면 더 자세한 답변을 드릴 수 있을 것 같아요. 어떤 도움이 필요하신지 추가적으로 알려주세요. 감사합니다.