티스토리 뷰

단위 테스트 JPAQueryFactory에 대해 mocking하기

● 단위테스트할 함수

@Service
@RequiredArgsConstructor
@Transactional
public class QueryFactoryTestService {

    private final JPAQueryFactory queryFactory;

    public boolean queryFactoryTest(int companyId) {
        return getFetchFirstCompany(companyId) != null;
    }

    private Company getFetchFirstCompany(int companyId) {
        return queryFactory
                .select(company)
                .from(company)
                .innerJoin(account).on(company.id.eq(account.company.id))
                .where(company.id.eq(companyId))
                .fetchFirst();
    }
}

● 테스트코드

아래와 같이 JPAQueryFactory 에 대해 mocking할 수 있다.

 

※ 주의사항

  • JPAQueryFactory 에 정의한 함수를 순서대로 return값을 정의해줘야 한다.
    ex) .select(company) -> from(company) -> innerJoin(account) ... (O)
         .from(company) -> .select(company) -> innerJoin(account) ... (X)
  • JPAQueryFactory 함수의 .(dot)을 기준으로 모든 return값을 정의해줘야 한다.
    ex) .(dot) 을 연결해서 return값은 정의할 수 없다.
    given(jpaQuery.innerJoin(account).on(any(Predicate.class))).willReturn(jpaQuery)  (X)
    -> given(jpaQuery.innerJoin(account)).willReturn(jpaQuery);  (O)
        given(jpaQuery.on(any(Predicate.class))).willReturn(jpaQuery); (O)
@ExtendWith(MockitoExtension.class)
class QueryFactoryTestServiceTest {

    @InjectMocks
    QueryFactoryTestService queryFactoryTestService;

    @Mock
    private JPAQueryFactory queryFactory;

    @Mock
    private JPAQuery<Company> jpaQuery;

    @Test
    @DisplayName("queryFactory test")
    void queryFactoryTest() {
        final Company responseCompany = Company.builder()
                                               .id(1)
                                               .name("회사명")
                                               .build();

        given(queryFactory.select(company)).willReturn(jpaQuery);
        given(jpaQuery.from(company)).willReturn(jpaQuery);
        given(jpaQuery.innerJoin(account)).willReturn(jpaQuery);
        given(jpaQuery.on(any(Predicate.class))).willReturn(jpaQuery);
        given(jpaQuery.where(any(Predicate.class))).willReturn(jpaQuery);
        given(jpaQuery.fetchFirst()).willReturn(responseCompany);

        final boolean isTest = queryFactoryTestService.queryFactoryTest(1);
        assertThat(isTest, equalTo(true));
    }
}

● 참고 URL

https://stackoverflow.com/questions/50491750/%20junit-mockito-and-querydsl-mysema-for-mocking-jpaqueryfactory

댓글
공지사항