如何在Java中更改Clock实例的内部状态?

huangapple go评论73阅读模式
英文:

How to change the internal state of a Clock instance in Java?

问题

我有一个用于验证日期过期的服务:

@RequiredArgsConstructor
public class ExpirationVerificationService {
  private final Clock clock;

  public boolean hasPassed(Instant instant) {
    return Instant.now(clock).isAfter(instant);
  }
}

我想要验证hasPassed方法随着时间的推移返回不同的值:

public class ExpirationVerificationServiceTest {

  private ExpirationVerificationService service;
  private Clock clock;

  @BeforeEach
  public void init() {
    clock = Clock.fixed(Instant.EPOCH, ZoneId.of("UTC"));
    service = new ExpirationVerificationService(clock);
  }

  @Test
  public void testHasExpired() {
    Instant instant = Instant.now(clock).plus(Duration.ofDays(30));
    assertFalse(service.hasPassed(instant));

    // TODO 将时钟调整到未来
    assertTrue(service.hasPassed(instant));
  }

}

如何更新Clock实例的内部状态以使其处于未来状态?

注:我正在测试的实际业务逻辑要比这个示例复杂得多(验证来自数据库的 OAuth 令牌的过期),我不能只是在过去使用不同的Instant实例。

英文:

I have a service that verifies expiration of dates:

@RequiredArgsConstructor
public class ExpirationVerificationService {
  private final Clock clock;

  public boolean hasPassed(Instant instant) {
    return Instant.now(clock).isAfter(instant);
  }
}

I want to verify that hasPassed returns different values as time passes:

public class ExpirationVerificationServiceTest {

  private ExpirationVerificationService service;
  private Clock clock;

  @BeforeEach
  public void init() {
    clock = Clock.fixed(Instant.EPOCH, ZoneId.of("UTC"));
    service = new ExpirationVerificationService(clock);
  }

  @Test
  public void testHasExpired() {
    Instant instant = Instant.now(clock).plus(Duration.ofDays(30);
    assertFalse(service.hasPassed(instant));

    // TODO move clock to future
    assertTrue(service.hasPassed(instant));
  }

}

How can I update the internal state of the Clock instance to be in the future?

note: the actual business logic I'm testing is much more complicated than this example (verifying expiration of Oauth tokens coming from a DB), I can't just use a different Instant instance in the past.

答案1

得分: 2

Clock 实际上只是 Instant 的提供者。您可以轻松地声明一个固定的时钟,如下所示:

Instant fixedInstant = Instant.EPOCH;
Clock clock = () -> fixedInstant;

因此,如果您想要一个可设置的 Clock,您可以这样声明:

AtomicReference<Instant> theInstant = new AtomicReference<>(Instant.EPOCH);
Clock clock = () -> theInstant.get();

然后更新 theInstant

英文:

Clock is effectively just a provider of an Instant. You can trivially declare a fixed clock like:

Instant fixedInstant = Instant.EPOCH;
Clock clock = () -&gt; fixedInstant;

As such, if you want a settable Clock, you could declare:

AtomicReference&lt;Instant&gt; theInstant = new AtomicReference&lt;&gt;(Instant.EPOCH);
Clock clock = () -&gt; theInstant.get();

and then update theInstant.

huangapple
  • 本文由 发表于 2020年10月20日 00:54:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/64431899.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定