模拟DateFormat,SimpleDateFormat,Date类

问题描述 投票:-1回答:2

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

我已经尝试过模拟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时间。

java unit-testing junit mockito powermockito
2个回答
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 ) ;

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的实际实现,并获得当前日期。

© www.soinside.com 2019 - 2024. All rights reserved.