시간 존재 단위 테스트
결과가 현재 시간에 따라 달라지는 함수를 테스트해야합니다 (조다 시간 사용 isBeforeNow()
).
public boolean isAvailable() {
return (this.someDate.isBeforeNow());
}
함수를 안정적으로 사용할 수 있도록 (예를 들어 Mockito를 사용하여) 시스템 시간을 스텁 / 모의 할 수 있습니까?
Joda은 time- 클래스 의 setCurrentMillisFixed
및 setCurrentMillisOffset
메서드를 통해 "가짜"현재 시간 설정을 지원합니다 DateTimeUtils
.
참조 https://www.joda.org/joda-time/apidocs/org/joda/time/DateTimeUtils.html를
코드를 테스트 가능하게 만드는 가장 좋은 방법 (IMO) 현재 사용하는 구현과 시간을 접근 할 수있는 구현을 사용하여 "현재 시간"의 시스템을 자체 인터페이스로 추출하는 것입니다. , 원하는대로 진행하십시오.
저는이 접근 방식을 다양한 상황에서 왔으며 잘 작동했습니다. 설정하는 것은 제출 Clock
. 원하는 형식 (예 : Joda Time 사용 또는 가능 Date
)으로 현재 순간을 제공하는 단일 메소드가있는 인터페이스 (예 :)를 만듭니다.
Java 8 은 테스트를 대체 구현을 허용 하는 추상 클래스 를 도입했습니다 . 이것은 그 제안의 대답에서 제안한 것입니다.java.time.Clock
Jon Skeet의 답변에 추가하기 위해 Joda Time에는 이미 현재 시간 인터페이스 인 DateTimeUtils.MillisProvider 가 포함되어 있습니다.
예를 들면 :
import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils.MillisProvider;
public class Check {
private final MillisProvider millisProvider;
private final DateTime someDate;
public Check(MillisProvider millisProvider, DateTime someDate) {
this.millisProvider = millisProvider;
this.someDate = someDate;
}
public boolean isAvailable() {
long now = millisProvider.getMillis();
return (someDate.isBefore(now));
}
}
단위 테스트에서 시간을 모의합니다 ( Mockito를 사용 하지만 자체 클래스 MillisProviderMock을 구현할 수 있음).
DateTime fakeNow = new DateTime(2016, DateTimeConstants.MARCH, 28, 9, 10);
MillisProvider mockMillisProvider = mock(MillisProvider.class);
when(mockMillisProvider.getMillis()).thenReturn(fakeNow.getMillis());
Check check = new Check(mockMillisProvider, someDate);
( DateTimeUtils.SYSTEM_MILLIS_PROVIDER 는 2.9.3의 Joda 시간에 추가됨) 을 사용합니다 .
Check check = new Check(DateTimeUtils.SYSTEM_MILLIS_PROVIDER, someDate);
저는 Jon과 접근 방식을 사용하지만 현재 시간 (예 :)에 대한 특수 인터페이스를 대신 Clock
일반적으로 특수 테스트 인터페이스 (예 :)를 만듭니다 MockupFactory
. 코드를 테스트하는 데 필요한 모든 방법을 거기에 넣었습니다. 예를 들어, 내 프로젝트 중 하나에는 네 가지 방법이 있습니다.
- 목업 데이터베이스를 반환하는 것;
- 데이터베이스의 변경 사항에 대해 알리는 객체 알림을 생성하는 하나;
- 내가 원할 때 작업을 실행하는 모형 java.util.Timer를 생성하는 하나;
- 현재 시간을 반환합니다.
테스트중인 클래스는 다른 인수 중에서 허용하는 생성자가 있습니다. 이 인수가없는 것은 "실제"에서 작동하는 인터페이스의 기본 인스턴스를 생성합니다. 인터페이스와 생성자는 모두 패키지 비공개 테스트 API가 패키지 외부로 유출되지 않습니다.
모방 된 개체가 더 필요하면 해당 인터페이스에 메소드를 추가하고 테스트 및 실제 구현을 구현합니다.
이런 식으로 코드 자체에 너무 많은 부담을주지 않고 처음부터 테스트에 코드를 디자인합니다. 실제로 많은 팩토리 코드가 한곳에 모이기 때문에 코드가 더 깔끔해집니다. 예를 들어 실제 코드에서 다른 데이터베이스 클라이언트 구현으로 전환해야하는 경우 생성자에 대한 참조를 검색하는 대신 줄만 수정하면됩니다.
물론 Jon의 접근 방식과 마찬가지로 수정할 수 없거나 수정할 수없는 타사 코드에서는 작동하지 않습니다.
참고 URL : https://stackoverflow.com/questions/5622194/time-dependent-unit-tests
'ProgramingTip' 카테고리의 다른 글
Objective-C : @interface 전에 @class 지시문? (0) | 2020.10.25 |
---|---|
경고 : 고유 한 배열 또는 반복기의 각 하위에는 한 "키"소품이 있어야합니다. (0) | 2020.10.25 |
NSString의 마지막 문자 제거 (0) | 2020.10.25 |
탐색 컨트롤러 사용자 지정 전환 애니메이션 (0) | 2020.10.25 |
Java에서 여러 생성 손상을 처리하는 가장 좋은 방법 (0) | 2020.10.25 |