본문 바로가기
Spring

[Spring] TDD Service 단에서 doAnswer

by windy7271 2025. 1. 1.
728x90
반응형

 
doanswer 는
일반적인 when-thenReturn 구조와 달리, 전달된 매개변수를 기반으로 동적 로딩을 처리하거나, 반환값을 계산 할때 사용합니다.
 
when-thenreturn은 호출되는 메서드의 인수와 상관없이 항상 동일 값을 반환하기 때문에, 로직없이 간단한 테스트시에 유용합니다.
 
하지만 저는 주어진 기간에 맞으면서 raw 하게 데이터들을 가져오는 서비스를 개발하고 있었습니다.
 

final LocalDate start = LocalDate.of(2024, 11, 11);
final LocalDate end = LocalDate.of(2024, 11, 13);

List<Long> executionIds = List.of(1L, 2L, 3L);
doReturn(executionIds).when(executionRepository).findExecutionIdsByCampaignId(any());

Execution execution1 = newExecution(1L,1L, "Product A", "Category A");
Execution execution2 = newExecution(2L,2L, "Product B", "Category B");
Execution execution3 = newExecution(3L,3L, "Product C", "Category C");

 
일단 executionIds 가 필요했기 때문에 다음과 같이 해주었습니다.
 
그다음 목데이터가 필요했는데요 

List<CampaignOptionDetails> campaignOptionDetailsList = List.of(
        newCampaignOptionDetails(1L, 데이터들),
        newCampaignOptionDetails(2L, 데이터들),
        newCampaignOptionDetails(3L, 데이터들), // 속하지 않는 데이터
        newCampaignOptionDetails(4L, 데이터들)
);

데이터들이라고 바꿔놨지만 저기안에 시작날짜와 끝날짜도 들어있었습니다. 
 
그리고 doAnswer를 사용하여 
날짜 범위를 기반으로 데이터를 필터링해보겠습니다.
 

doAnswer(data -> {
    List<Long> ids = data.getArgument(0);
    LocalDate from = data.getArgument(1);
    LocalDate to = data.getArgument(2);
    return campaignOptionDetailsList.stream()
            .filter(detail -> ids.contains(detail.getExecution().getId()) &&
                    (detail.getCopDate().isEqual(from) || detail.getCopDate().isAfter(from)) &&
                    (detail.getCopDate().isEqual(to) || detail.getCopDate().isBefore(to)))
            .toList();
}).when(campaignOptionDetailsRepository)
        .findByExecutionIdsAndDateRange(any(List.class), any(LocalDate.class), any(LocalDate.class));

 
 
campaignOptionDetailsRepository.findByExecutionIdsAndDateRange 을 호출시 doAnswer로 동작을 정의합니다.
위에 data 안에 ids, 시작날짜, 끝날짜가 들어가게 되는것이지요
 
그러면  밑에 스트림을 통해 ids들이 id에 들어있으면서, 시작날짜와 끝날짜 사이인것들만 나오게 됩니다.
 

 

반응형

댓글