The closest thing is the Clock object. You can create a Clock object using any time you want (or from the System current time). All date.time objects have overloaded now methods that take a clock object instead for the current time. So you can use dependency injection to inject a Clock with a specific time:
public class MyBean {
private Clock clock; // dependency inject
...
public void process(LocalDate eventDate) {
if (eventDate.isBefore(LocalDate.now(clock)) {
...
}
}
}
You can use JMockit or PowerMock to mock static method invocations in your test code.
Example with JMockit:
@Test
public void testSth() {
LocalDate today = LocalDate.of(2000, 6, 1);
new Expectations(LocalDate.class) \{\{
LocalDate.now(); result = today;
}};
Assert.assertEquals(LocalDate.now(), today);
}
EDIT: After reading the comments on Jon Skeet's answer to a similar question here on SO I disagree with my past self. More than anything else the argument convinced me that you cannot parallize tests when you mock static methods.
You can/must still use static mocking if you have to deal with legacy code, though.
Here's a working way to override current system time to a specific date for JUnit testing purposes in a Java 8 web application with EasyMock
Joda Time is sure nice (thank you Stephen, Brian, you've made our world a better place) but I wasn't allowed to use it.
After some experimenting, I eventually came up with a way to mock time to a specific date in Java 8's java.time API with EasyMock
Without Joda Time API
Without PowerMock.
Here's what needs to be done:
What needs to be done in the tested class
Step 1
Add a new java.time.Clock attribute to the tested class MyService and make sure the new attribute will be initialized properly at default values with an instantiation block or a constructor:
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
// (...)
}
Step 2
Inject the new attribute clock into the method which calls for a current date-time. For instance, in my case I had to perform a check of whether a date stored in database happened before LocalDateTime.now(), which I replaced with LocalDateTime.now(clock), like so:
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();
}
}
// (...)
}
What needs to be done in the test class
Step 3
In the test class, create a mock clock object and inject it into the tested class's instance just before you call the tested method doExecute(), then reset it back right afterwards, like so:
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(..)
}
}
Check it in debug mode and you will see the date of 2017 Feb 3 has been correctly injected into myService instance and used in the comparison instruction, and then has been properly reset to current date with initDefaultClock().
A bit late, but here it is what I use to mock time using the java.date API in Kotlin:
val now = LocalDate.of(2021, Month.FEBRUARY, 19)
val clock = Clock.fixed(Instant.ofEpochSecond(
now.atStartOfDay().toEpochSecond(ZoneOffset.UTC)
), ZoneId.systemDefault())
and then you can pass your clock to the class to test
val classToTest = MyClass(clock)
Of course, inside your testable class you will use the clock to retrieve dates or times:
class MyClass(private val clock: Clock = Clock.systemDefaultZone()) {
// ...
fun doSomething() = LocalDate.now(clock)...
// Mocking time as 9am
final String mockTime = "09:00:00"
new MockUp<LocalTime>() {
@Mock
public LocalTime now() {
return LocalTime.parse(mockTime);
}
};