LocalDate mock 적용

개발하는 구황작물·2023년 2월 7일
0

개인 프로젝트

목록 보기
1/9

개인 플젝 Unit Test 작성 중 LocalDate를 테스트에 적용해야 했다.

public double getPercentage(Long usersId) {
        int findAll = todoRepository.findByDate(usersId, LocalDate.now());
        int findAllDone = todoRepository.findByDateAndStatus(usersId, LocalDate.now());
...
    }

Unit test 적용을 위해 LocalDate를 Mocking하려 했으나 mockito에서 when 메서드의 인자값으로 '호출이 되는 메소드'
를 넣어줘야 하는데 static메서드가 들어가서 인식이 되지 않았다.

doReturn(3).when(todoRepository)
	.findByDate(anyLong(), LocalDate.now()); --> (x)

이를 해결할 수 있는 여러 방법이 있었으나 그 중 Clock를 이용하기로 하였다.

LocalDate.now() 자체를 Mocking 하는 방법도 있으나 이방법은 안티패턴이라고 한다
LocalDate.now()는 기본 시간대의 시스템 시계에서 현재 날자를 가져온다고 한다.
이 방법은 clock이 하드코딩되어있어 테스트를 위한 대체 clock을 사용할 수가 없다고 한다...

  1. Clock Bean으로 등록하기
@Configuration
public class TimeConfig {

    @Bean
    public Clock clock() {
        return Clock.systemDefaultZone();
    }
}
  1. LocalDate.now() 대신 LocalDate.now()에 Clock를 DI 하여 사용한다.

LocalDate.now() -> LocalDate.now(Clock)


@Transactional
@Service
@RequiredArgsConstructor
public class AttendService {
    private final Clock clock;
    
	public double getPercentage(Long usersId) {
        LocalDate now = LocalDate.now(clock);
        int findAll = todoRepository.findByDate(usersId, now);
        int findAllDone = todoRepository.findByDateAndStatus(usersId, now);
...
    }
}
  1. Test code에 clock.instant()를 Mocking 하고 사용한다.
@ExtendWith(MockitoExtension.class)
public class AttendServiceTest {

	@Mock
    private Clock clock;
    
    private final static LocalDate LOCAL_DATE = LocalDate.of(2023, 2, 7);
    
    ...

@Test
    void getPercentage() {
        fixedClock = Clock.fixed(LOCAL_DATE.atStartOfDay(ZoneId.systemDefault()).toInstant(), ZoneId.systemDefault());
        doReturn(fixedClock.instant()).when(clock).instant();
        doReturn(fixedClock.getZone()).when(clock).getZone();
 		doReturn(3)
 			.when(todoRepository).findByDate(anyLong(), eq(LocalDate.now(fixedClock)));
		doReturn(1)
        	.when(todoRepository).findByDateAndStatus(anyLong(), eq(LocalDate.now(fixedClock)));       
        }
 }
 ...
profile
어쩌다보니 개발하게 된 구황작물

0개의 댓글