模拟DateFormat,SimpleDateFormat,Date类

时间:2019-04-30 12:51:26

标签: java unit-testing junit mockito powermockito

我需要模拟所需的类并获得所需的日期结果。

我已经尝试在DateFormat类中模拟format()函数,但是没有用。

class XYZ {

   private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
   private static final TimeZone UTC = TimeZone.getTimeZone("UTC");

   public void buildStr(StringBuilder str){
     DATE_FORMAT.setTimeZone(UTC);
     Date date = getDate();
     str.append(DATE_FORMAT.format(date));
   }

   private Date getDate(){
     return new Date();
   }

}

在此代码中,我希望将星形附加“ 20190430000000”(恰好是此值) 但是我正在获取当前的UTC时间。

2 个答案:

答案 0 :(得分:0)

您可以使用固定日期

LocalDate date = LocalDate.parse("20190430000000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

此代码示例将在java8或更高版本上工作。

EDIT1:

假设:您要编写一个使用固定日期的测试,而在生产环境中使用当前日期。您可以使用JUnit,某种形式的依赖注入和Mockito。

这是一个不会直接编译的抽象示例。

class XYZ {
    @Inject
    private DateProvider dateProvider;

    public void buildStr(StringBuilder str){
        LocalDate date = dateProvider.getDate();

        // do something with date
    }
}

class DateProvider {
    public Date getDate() {
        return new Date();
    }
}

class XYZTest {
    @Mock
    private DateProvider dateProvider;

    @InjectMocks
    private XYZ xyz;

    @Test
    public void test() {
        LocalDate fixedDate = LocalDate.parse("20190430000000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        when(dateProvider.getDate()).thenReturn(fixedDate);

        StringBuilder builder = new StringBuilder();
        xyz.buildStr(builder);

        // verify builder contains what you expect
    }
}

在服务类中,您定义了一个提供日期的附加组件(此处为DateProvider)。在测试中,您可以通过Mocktio提供的注释@InjectMocks获得服务的可测试实例。它将把带有@Mock注释的任何字段作为模拟注入到您的可测试实例中。在测试中,您定义when().thenReturn()进行模拟操作的方式。您的生产代码将使用DateProvider的实际实现,并获得当前日期。

答案 1 :(得分:0)

java.time

您使用的是可怕的日期时间类,而这些类在几年前已被JSR 310中定义的现代 java.time 类所取代。

Clock

java.time 类采用可选的Clock参数。通过Clock对象,使其具有测试所需的行为。 Clock类具有提供几种特殊行为的静态方法。这些包括固定的时刻,在真实时钟之前或之后设置一定时间的滚动时刻,以及更改的节奏(例如整分钟增加)。

Stack Overflow已对此问题进行了多次讨论。搜索以了解更多信息。

LocalDate ld = LocalDate.of( 2019 , Month.APRIL , 30 ) ;
ZoneId z = ZoneId.of( "America/Edmonton" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;
Clock clock = Clock.fixed( instant , z ) ;

现在将clock对象插入测试中。

ZonedDateTime zdt = ZonedDateTime.now( clock ) ;

当您想要一个真实的时钟时,请使用:

Clock clock = Clock.system( z ) ;