【问题标题】:how to mock timestamp and date function in java?如何在java中模拟时间戳和日期函数?
【发布时间】:2019-07-04 22:09:18
【问题描述】:

如何模拟以下代码?我不想更改我的代码。

Date date = new Date();
String res_timestamp=new Timestamp(date.getTime()).toString();

我的代码:

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("PST"));
    Date NOW = sdf.parse("2019-02-11 00:00:00");
    Timestamp time=new Timestamp(NOW.getTime());
    whenNew(Timestamp.class).withNoArguments().thenReturn(time);

我如何模拟它?我发现很难嘲笑它。

我该如何解决?

注意:我不想更改我的代码。在不更改我的代码的情况下,我必须模拟这两行。

【问题讨论】:

标签: java date junit timestamp powermockito


【解决方案1】:

tl;博士

  • 使用java.time.ClockZonedDateTimeInstantZoneId
  • 将更改后的Clock 对象作为依赖项注入:Clock.fixed( … )
  • 切勿使用DateCalendarSimpleDateFormatTimestampTimeZone

将更改后的 Clock 对象作为依赖项传递

您正在使用 terrible 日期时间类,这些类在几年前被 JSR 310 定义的 java.time 类所取代。

java.time.Clock 类提供了几种适合测试的替代行为。这些包括一个固定的时间点、改变的节奏,以及从当前时刻开始的调整。

将这些Clock 对象之一传递给java.time 类中的各种方法,以供您进行测试。

PST 不是时区。以Continent/Region 的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 2-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。

ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;

建立您为测试考虑的特定时刻。

LocalDate ld = LocalDate.of( 2019 , 2 , 11 ) ;
LocalTime lt = LocalTime.MIN ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

zdt.toString(): 2019-02-11T00:00-08:00[美国/洛杉矶]

调用Clock.fixed 需要Instant,即UTC 时间。我们可以通过提取Instant 将我们的区域值调整为 UTC。同一时刻,时间轴上的同一点,不同的挂钟时间。

Instant instant = zdt.toInstant() ;

instant.toString(): 2019-02-11T08:00:00Z

指定一个Clock,它将永远将当前时刻报告为该特定时刻,而不增加。

Clock clock = Clock.fixed( instant , z ) ;

clock.toString(): FixedClock[2019-02-11T08:00:00Z,America/Los_Angeles]

将固定时钟作为依赖注入。

Instant now = Instant.now( clock ) ;  // Tell me a lie.

now.toString(): 2019-02-11T08:00:00Z

看到这个code run live at IdeOne.com

JDBC 4.2

如果您要实例化 java.sql.Timestamp 以用于数据库,请改用 java.time 类。从JDBC 4.2 开始,我们可以与数据库交换java.time 对象。

您的JDBC driver 可能有对Instant 的可选支持。

myPreparedStatement.setObject( … , instant ) ;            // Storing data.
Instant instant = myResultSet.get( … , Instant.class ) ;  // Retrieving data.

您的驱动程序必须支持OffsetDateTime

myPreparedStatement.setObject( … , instant.atOffset( ZoneOffset.UTC ) ) ;            // Storing data.
OffsetDateTime odt = myResultSet.get( … , OffsetDateTime.class ) ;  // Retrieving data.

Adjust into a time zone.

ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    猜你喜欢
    • 2013-11-03
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 2018-08-09
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多