ProgramingTip

시간 존재 단위 테스트

bestdevel 2020. 10. 25. 12:42
반응형

시간 존재 단위 테스트


결과가 현재 시간에 따라 달라지는 함수를 테스트해야합니다 (조다 시간 사용 isBeforeNow()).

    public boolean isAvailable() {
    return (this.someDate.isBeforeNow());
}

함수를 안정적으로 사용할 수 있도록 (예를 들어 Mockito를 사용하여) 시스템 시간을 스텁 / 모의 할 수 있습니까?


Joda은 time- 클래스 setCurrentMillisFixedsetCurrentMillisOffset메서드를 통해 "가짜"현재 시간 설정을 지원합니다 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

반응형