작성
·
491
0
당연히 구글링 해보셨져? 원하는 결과를 못찾으셨나요? 어떤 검색어를 입력했는지 알려주세
문제가 발생한 코드(프로젝트)를 Github에 올리시고 링크를 알려주세요.
안녕하세요. 호돌맨님.
postService에서 목록 조회하는 단위테스트에 대해서 질문이 있습니다.
먼저 목록 조회 코드부터 보여드리면
postService.findPosts 는 postQueryRepository에 구현체로 만들었습니다.
postService
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class PostService {
public static final String ENTITY_NAME = "post";
private final PostQueryRepository postQueryRepository;
private final PostRepository postRepository;
/**
* Post 목록 조회
*/
public Page<Post> findPosts(PostSearchCondition condition, Pageable pageable) {
return postQueryRepository.findPosts(condition, pageable);
}
}
postQueryRepository
@Repository
public class PostQueryRepository {
private final JPAQueryFactory queryFactory;
public PostQueryRepository(EntityManager em) {
this.queryFactory = new JPAQueryFactory(em);
}
/**
* Post 목록 조회
*/
public Page<Post> findPosts(PostSearchCondition condition, Pageable pageable) {
List<Post> content = getPostList(condition, pageable);
JPAQuery<Long> count = getPostListCount(condition);
return PageableExecutionUtils.getPage(content, pageable, count::fetchOne);
}
/**
* Post 목록
*/
private List<Post> getPostList(PostSearchCondition condition, Pageable pageable) {
return queryFactory
.select(post)
.from(post)
.where(
searchCondition(condition.getSearchCondition(), condition.getSearchKeyword())
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(post.id.desc())
.fetch();
}
/**
* Post 목록 카운트
*/
private JPAQuery<Long> getPostListCount(PostSearchCondition condition) {
return queryFactory
.select(post.count())
.from(post)
.where(
searchCondition(condition.getSearchCondition(), condition.getSearchKeyword())
);
}
/**
* where searchCondition LIKE '%searchKeyword%'
*/
private BooleanExpression searchCondition(SearchCondition searchCondition, String searchKeyword) {
if (searchCondition == null || !hasText(searchKeyword)) {
return null;
}
if (SearchCondition.TITLE.equals(searchCondition)) {
return post.title.contains(searchKeyword);
} else if (SearchCondition.CONTENT.equals(searchCondition)) {
return post.content.contains(searchKeyword);
} else {
return null;
}
}
}
다음은 테스트 코드입니다.
postServiceTest
@ExtendWith(MockitoExtension.class)
class PostServiceTest {
//CREATE_POST
public static final String POST_TITLE = "post_title";
public static final String POST_CONTENT = "post_content";
//UPDATE_POST
public static final String UPDATE_TITLE = "update_title";
public static final String UPDATE_CONTENT = "update_content";
//ERROR_MESSAGE
public static final String ENTITY_NAME = "post";
public static final Long NOT_FOUND_ID = 1L;
public static final String HAS_MESSAGE_STARTING_WITH = "존재하지 않는 ";
public static final String HAS_MESSAGE_ENDING_WITH = "id = ";
@InjectMocks PostService postService;
@Mock PostQueryRepository postQueryRepository;
@Mock PostRepository postRepository;
private Post getPost(String title, String content) {
return Post.createPostBuilder()
.title(title)
.content(content)
.build();
}
@Test
@DisplayName("post 목록 조회")
void findPosts() {
//given
List<Post> posts = new ArrayList<>();
for (int i = 0; i < 30; i++) {
posts.add(getPost(POST_TITLE + i, POST_CONTENT));
}
//검색 안먹힘
PostSearchCondition condition = new PostSearchCondition();
condition.setSearchCondition(SearchCondition.TITLE);
condition.setSearchKeyword("0");
PageRequest pageRequest = PageRequest.of(0, 10);
given(postQueryRepository.findPosts(condition, pageRequest)).willReturn(new PageImpl<>(posts));
//when
Page<Post> contents = postService.findPosts(condition, pageRequest);
//then
assertThat(contents.getTotalElements()).isEqualTo(3);
assertThat(contents.getContent().size()).isEqualTo(3);
}
}
여기서 findPosts 단위 테스트를 진행하려고 하는데요.
목록을 30개를 만들고 검색조건과 페이지 정보를 파라미터로 넘겨서 검색이 된 결과가 나올것이라고 예상했지만 검색조건은 먹히지 않고 30개의 목록만 리턴이 됩니다.
전 검색 조건대로 "0"들어간 title만 검색이되어서
contents.getTotalElements() == 3, contents.getcontent().size() == 3 으로 예상을 했는데
contents.getTotalElements() == 30, contents.getcontent().size() == 30 로 결과가 나와 테스트에 실패하게됩니다.
구글링으로 mockito, page, test, querydsl, parameter 등 다양하게 검색 해봤는데 원하는 결과를 얻기 못해 질문 한번 드려봅니다.
혹시나 제가 잘못된 방향으로 테스트를 진행하고 있는건지 혹은 다른 방법이 있을지 궁금합니다!
깃저장소도 같이 공유드립니다.
https://github.com/heechul90/heech-heechlog-server
답변 1
0
안녕하세요. 호돌맨입니다.
given(postQueryRepository.findPosts(condition, pageRequest)).willReturn(new PageImpl<>(posts));
위 코드에서 postQueryRepository.findPosts
를 할 경우 posts(30개)를 반환하도록 설정 하셨기 3개가 나올 수 없습니다.
그치만.. 코드쨩.. 분명 PostSearchCondition으로 필터링 했는걸?
postQueryRepositorys는 Mock 상태입니다. Mock은 실제로 findPosts
코드를 실행하지 않습니다.
확인 해보시려면 PostQueryRepository.java안에 findPosts 첫 번째 라인에 breakpoint를 찍으신 뒤 debug 모드로 테스트를 실행하시면 breakpoint가 걸리지 않는 걸 확인해보실 수 있습니다.
QueryDSL 테스트시 @DataJpaTest검색 해보시는걸 추천드립니다.
감사합니다.