I need to be able to fake the system time when testing. The source I have makes use of java.time.LocalDate. Is there a way to make LocalDate.now()
return a pre-set date?

- 4,368
- 5
- 44
- 72
-
2Make a wrapper method for calls to `LocalDate.now` and let it return your values if you're in a test case. – Binkan Salaryman Mar 13 '15 at 17:40
-
1There is an overload of LocalDate.now which accepts a Clock. Can you use that? – Andy Turner Mar 13 '15 at 17:41
-
You really should be injecting a Clock rather than trying to fake the system time. – Louis Wasserman Mar 13 '15 at 18:58
-
You can refer to the below link. https://stackoverflow.com/a/65014036/11628537 – Ghanshyam Parmar Nov 26 '20 at 19:16
6 Answers
There are a few options you've:
Wrap the
LocalDate.now()
call in a non-static method of a class. Then you can mock that method to return your specific instance - This would not seem practical if you're directly callingLocalDate.now()
method at many places in your code.Use
LocalDate.now(Clock)
method, that is pretty test-friendly, as already suggested in comments - again you've to modify your application code.Use
Powermockito
, if you can. In that case, you've a pretty easy approach by mocking static methods usingmockStatic(Class<?>)
method.
The 3rd approach can be implemented as:
@PrepareForTest({ LocalDate.class })
@RunWith(PowerMockRunner.class)
public class DateTest {
@Test
public void yourTest() {
PowerMockito.mockStatic(LocalDate.class);
when(LocalDate.now()).thenReturn(yourLocalDateObj);
}
}

- 209,639
- 45
- 409
- 525
-
3You may need to put your class into list of prepared ones: `@PrepareForTest({MyFooService.class, LocalDate.class})` – Andrey Lebedenko Jan 23 '18 at 16:57
-
How do I mock this line of code to return 2020-02-27 LocalDate.now().plusDays(Long.parseLong("0")).toString() but when it come to that line it returns todays date – yatinbc Mar 03 '20 at 15:05
-
Hi there. I just have a question about the 3rd approach listed here. When I attempt to do this, I get a NoSuchMethodError for the call to LocalDate.now(). Any idea why this might happen. I used the exact code that is shown in this example using my own 'yourLocalDateObj' defined as ```LocalDate localDate = PowerMockito.mock(LocalDate.class); ``` – Shaun Aran Jan 05 '22 at 14:00
I would usually suggest using Mockito, but since the method is static, you can't really mock the object.
Why not have some "DateProvider" class grab the date for you
public class DateProvider{
public LocalDate getNow(){
return LocalDate.now();
}
}
and use it thusly:
new DateProvider().getNow();
That would make it fairly easy to test with any LocalDate return value

- 770
- 5
- 9
Can you dependency inject the time through the constructor / parameter of the code?
Otherwise you can wrap LocalDate.now() in a static class that lets you hard-code a value for testing.

- 29,524
- 10
- 61
- 76
I was trying the code on this page but I noticed I should get the LocalDate instance first before to use PowerMockito as the 2 firstLines of the next code
@Test
public void testYearOptions() throws Exception{
LocalDate date = LocalDate.of(2015,11,12);
PowerMockito.mockStatic(LocalDate.class);
Mockito.when(LocalDate.now()).thenReturn(date);
Map<String, String> semesterMap = Utilities.getYears(); //Your function where LocalDate is Uses
assertNotNull(yearsMap.get("2015"));//your assertion
}

- 749
- 11
- 28
No need of spaghetti code here: keep it simple! Write a convenience method and change its body to meet your needs.
public static LocalDate getCurrentTime() {
// You can comment right code to save it during debugging
}

- 8,370
- 15
- 50
- 83
For testing:
@RunWith(SpringRunner.class)
@SpringBootTest
public class DateTimeFactoryTest {
private static final Logger log = LoggerFactory.getLogger(DateTimeFactoryTest.class);
@MockBean
DateTimeFactory dateTimeFactory;
@Test
public void test001() throws MissingMethodInvocationException {
given(dateTimeFactory.getLocalDate()).willReturn(LocalDate.of(2017,4, 4));
LocalDate ld = dateTimeFactory.getLocalDate();
}
}

- 407
- 9
- 15
-
How do I mock this line of code to return 2020-02-27 LocalDate.now().plusDays(Long.parseLong("0")).toString() but when it come to that line it returns todays date – yatinbc Mar 03 '20 at 15:05