테스트 코드 작성 중 오류 - 1

김원기·2024년 7월 5일

트러블 슈팅

목록 보기
1/5
post-thumbnail

UnnecessaryStubbingException

@Test
    public void deletePostLike() {
        User user = new User();
        Post post = new Post();
        PostLike postLike = new PostLike();
        QPostLike qPostLike = QPostLike.postLike;

        JPADeleteClause deleteClause = Mockito.mock(JPADeleteClause.class);
        when(queryFactory.delete(qPostLike)).thenReturn(deleteClause);
        when(deleteClause.where(qPostLike.user.eq(user).and(qPostLike.post.eq(post)))).thenReturn(deleteClause);
        when(deleteClause.execute());

    }

여기서 UnnecessaryStubbingException: 오류가 발생했다.

일단 처음에 오류 코드와 힌트를 보면

Following stubbings are unnecessary (click to navigate to relevant line of code):
  1. -> at com.sparta.easyspring.postlike.repository.PostLikeRepositoryCustomImplTest.deletePostLike(PostLikeRepositoryCustomImplTest.java:66)
  2. -> at com.sparta.easyspring.postlike.repository.PostLikeRepositoryCustomImplTest.deletePostLike(PostLikeRepositoryCustomImplTest.java:67)
Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class.

라고 하면서 lenient를 사용하라고 하기에

lenient().when(queryFactory.delete(qPostLike)).thenReturn(deleteClause);
lenient().when(deleteClause.where(qPostLike.user.eq(user).and(qPostLike.post.eq(post)))).thenReturn(deleteClause);
when(deleteClause.execute());

이렇게만 수정했는데

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at com.sparta.easyspring.postlike.repository.PostLikeRepositoryCustomImplTest.deletePostLike(PostLikeRepositoryCustomImplTest.java:69)

E.g. thenReturn() may be missing.

마지막줄에 thenReturn이 빠졌다고 한다.... 이런

lenient().when(queryFactory.delete(qPostLike)).thenReturn(deleteClause);
lenient().when(deleteClause.where(qPostLike.user.eq(user).and(qPostLike.post.eq(post)))).thenReturn(deleteClause);
lenient().when(deleteClause.execute()).thenReturn(1L);

thenReturn을 추가하면서 빠졌던 lenient()도 추가해주자.

where(any())

@Test
    void testFindPostLikeByUserAndPost() {
        User user = new User();
        Post post = new Post();
        PostLike postLike = new PostLike();

        JPAQuery<PostLike> query = new JPAQuery<>();
        when(queryFactory.selectFrom(qPostLike)).thenReturn(query);
        when(query.where(any(BooleanExpression.class))).thenReturn(query);
        when(query.fetchOne()).thenReturn(postLike);

        Optional<PostLike> result = postLikeRepository.findPostLikeByUserAndPost(user, post);

        assertThat(result).isPresent();
        assertThat(result.get()).isEqualTo(postLike);
    }

예전글을 찾아보거나 그래도 안되어서 GPT같은 곳에 물어보아도
when(query.where(any(BooleanExpression.class))).thenReturn(query);
혹은
when(query.where(any())).thenReturn(query);
이렇게 any() 자체를 where의 조건에 넣는 경우가 있어서 헷갈렸는데

이번에 Repository자체를 QueryDSL로 구현하면서

@Override
    public Optional<PostLike> findPostLikeByUserAndPost(User user, Post post) {
        QPostLike postLike = QPostLike.postLike;

        PostLike foundPostLike = queryFactory
                .selectFrom(postLike)
                .where(postLike.user.eq(user)
                        .and(postLike.post.eq(post)))
                .fetchOne();

        return Optional.ofNullable(foundPostLike);
    }

Query문을 구체적으로 구현하기 때문에 이 조건을 사용하는 방식으로 해결했다.

profile
혼자 공부하는 블로그라 부족함이 많아요 https://www.notion.so/18067a27ac7e4f4790dde645fb3bf3d3?pvs=4

0개의 댓글