시간 관련 비즈니스 로직 테스트

Alex·2024년 11월 14일
0

Plaything

목록 보기
14/118

Plaything에서는 광고 시청, 매일 첫 로그인 마다 포인트를 제공하고 있다.

4시간마다 광고를 보면 포인트를 제공하는 방식이다.

그런데, 이 비즈니스 로직을 테스트하기가 어려웠다.

이런 메서드가 있다.
마지막으로 광고를 본 시간과 비교해야 할 시간은 서버에서 제공하는 타임라인이다.
하드코딩이 돼 있어서 내가 이 비교할 시간을 조절할 수가 없다.

그러니, 테스트할 때 4시간 뒤의 상황에서 보상을 받는지 확인할 수가 없는 것이다.

이 방법은 시간을 매개변수로 받으면 해결된다.

DTO로 현재 시간을 받고

그 시간으로 비교를 한다.

테스트는 무사히 잘 통과했다.

그런데 클라이언트는 쉽게 조작할 수 있지 않아?

클라이언트에서 검증을 맡기지 않는 이유는 클라이언트에서 오는 요청이 중간에 조작될 수 있어서다.

만약, 누군가 악의적으로 DTO에 담은 현재 시간을 4시간 뒤로 변경한다면??
그러면 계속 보상을 받을 수 있게 된다.

모킹을 할까 고민했는데 굳이 그럴 바엔
더 간단한 방법인 DTO에서 시간을 받는 게 아니라 컨트롤러에서 시간을 입력하는 방식을 쓸 수 있을 것 같았다.

이러면 외부 조작이 안된다.

그러면 이렇게 테스트를 할 때도 외부에서 시간을 주입해서 넣을 수가 있다.

근데 테스트가 왜 실패하지??..

시간을 매개변수로 하고서
오늘 로그인 한번, 그 다음날 로그인 한번하는 상황을 만들어서 진행했다.

그런데 두번째 날에 첫 로그인 보상이 들어오지 않았다.

아무 생각없이 plusDays(1)하고 equals를 하면 되겠지 했지만...
비교하는 두개의 시간에서 초/밀리초가 정확히 일치하지 않았다.
날짜상으로는 하루 뒤여도 equals를 해버리니

11월 15일, 11월 15일 두개가 밀리초가 달라서
다른 날짜로 인식되버렸다.

시간 관련 테스트는 위처럼 정확도를 낮추는 식으로 해야 한다.
근사치로 테스트를 해야 한다.

어차피 매일매일 첫 로그인을 하는 경우 보상을 주기 때문에
타입을 LocalDate로 바꿨다. 그리고 두개의 시간차가 하루이상일 때 보상을 주는 코드로 변경했다.

profile
답을 찾기 위해서 노력하는 사람

0개의 댓글