gpt4 book ai didi

junit - 如何使用 EasyMock(不使用 Joda Time 和 PowerMock)将当前系统时间覆盖到 Java 8 Web 应用程序中的特定日期?

转载 作者:行者123 更新时间:2023-12-02 01:54:22 28 4
gpt4 key购买 nike

我需要模拟时间(到特定日期,这意味着我可能不会使用 anyLong() ),以便在 Java 8 中仅使用 java.time 进行测试。 ,因此没有 Joda Time,在 EasyMock 下的测试环境中。

EasyMock 不允许您模拟静态方法,例如 LocalDateTime.now() 。 PowerMock 可以,但我不被允许使用 PowerMock。

Joda Time 库提供了一种简洁而优雅的方式来模拟时间 DateTimeUtils.setCurrentMillisFixed() ,和DateTimeUtils.setCurrentMillisSystem()回到当前时刻。

只有我不被允许使用Joda Time。

有人告诉我使用模拟时钟 java.time.Clock类实例并将其注入(inject) LocalDateTime.now()像这样:LocalDateTime.now(mockClock)

有没有办法在没有 Joda Time 的情况下正确实现它?没有 PowerMock

最佳答案

事情发生是有办法的。您需要执行以下操作:

被测试的类需要做什么

步骤 1

向测试类MyService添加一个新的java.time.Clock属性,并确保新属性将使用实例化 block 或构造函数:

import java.time.Clock;
import java.time.LocalDateTime;

public class MyService {
// (...)
private Clock clock;
public Clock getClock() { return clock; }
public void setClock(Clock newClock) { clock = newClock; }

public void initDefaultClock() {
setClock(
Clock.system(
Clock.systemDefaultZone().getZone()
// You can just as well use
// java.util.TimeZone.getDefault().toZoneId() instead
)
);
}
{
initDefaultClock(); // initialisation in an instantiation block, but
// it can be done in a constructor just as well
}
// (...)
}

步骤 2

将新属性clock注入(inject)到调用当前日期时间的方法中。例如,在我的例子中,我必须检查数据库中存储的日期是否发生在 LocalDateTime.now() 之前,我将其替换为 LocalDateTime.now(clock) >,像这样:

import java.time.Clock;
import java.time.LocalDateTime;

public class MyService {
// (...)
protected void doExecute() {
LocalDateTime dateToBeCompared = someLogic.whichReturns().aDate().fromDB();
while (dateToBeCompared.isBefore(LocalDateTime.now(clock))) {
someOtherLogic();
}
}
// (...)
}

测试类需要做什么

步骤 3

在测试类中,创建一个模拟时钟对象,并在调用测试方法 doExecute() 之前将其注入(inject)到测试类的实例中,然后立即将其重置回来,如下所示:

import java.time.Clock;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import org.junit.Test;

public class MyServiceTest {
// (...)
private int year = 2017; // Be this a specific
private int month = 2; // date we need
private int day = 3; // to simulate.

@Test
public void doExecuteTest() throws Exception {
// (...) EasyMock stuff like mock(..), expect(..), replay(..) and whatnot

MyService myService = new MyService();
Clock mockClock =
Clock.fixed(
LocalDateTime.of(year, month, day, 0, 0).toInstant(OffsetDateTime.now().getOffset()),
Clock.systemDefaultZone().getZone() // or java.util.TimeZone.getDefault().toZoneId()
);
myService.setClock(mockClock); // set it before calling the tested method

myService.doExecute(); // calling tested method

myService.initDefaultClock(); // reset the clock to default right afterwards with our own previously created method

// (...) remaining EasyMock stuff: verify(..) and assertEquals(..)
}
}

在 Debug模式下检查它,您将看到 2017 年 2 月 3 日的日期已正确注入(inject) myService 实例并在比较指令中使用,然后已使用 initDefaultClock()

关于junit - 如何使用 EasyMock(不使用 Joda Time 和 PowerMock)将当前系统时间覆盖到 Java 8 Web 应用程序中的特定日期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45801065/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com