1

I've got a problem with mocking ZoneDateTime and LocalTime (Java 8) using PowerMock.

I use

@RunWith(PowerMockRunner.class)
@PrepareForTest({ZonedDateTime.class, LocalTime.class, Util.class}) 

for class and in test method

mockStatic(ZonedDateTime.class, LocalTime.class, Util.class);

PowerMockito
    .doReturn(LocalTime.parse("23:56"))
    .when(LocalTime.class, "now");

PowerMockito
    .doReturn(ZonedDateTime.parse("2017-08-28T23:56:00Z", DateTimeFormatter.ISO_OFFSET_DATE_TIME))
    .when(ZonedDateTime.class, "now", ZoneId.of(AMERICA_CHICAGO_ZONE));

PowerMockito
    .doReturn("bombel")
    .when(Util.class, "test");

Unfortunately, first two cases don't mock static methods. The third one, "test" which is written by me is mocked.

How mock ZonedDateTime and LocalTime?

I have to be sure that "now" points in particular moment in time. I don't think that wrapping ZoneDatetime.now() by another method is a good idea. Tests shouldn't impact on source code.

bombel
  • 53
  • 1
  • 7
  • 5
    Why in the world would you mock `ZonedDateTime` and `LocalTime` ? I think they are already quite power tested, aren't they ? (I may be wrong) – Yassine Badache Dec 18 '17 at 14:05
  • 1
    Just create real instances of them. – Andy Turner Dec 18 '17 at 14:05
  • Because testing requires detailed control over the inputs of your software; that is why you mock the data sources. – Bob Dalgleish Dec 18 '17 at 14:07
  • 3
    An alternative is to use a Clock: https://stackoverflow.com/a/35774635/829571 – assylias Dec 18 '17 at 14:08
  • 4
    You can control inputs without mocking. Especially for self-contained value types without behavior, you can create instances with desired states. That's both easier than mocking and less fragile (behavior-preserving refactors don't break the tests). – Daniel Pryden Dec 18 '17 at 14:08
  • 1
    Mocking should be used to define what *your* objects are supposed to do with *your* parameters. It is a tool specifically created to *test* behavior of objects in order to be asserted. For your case, you should just instanciate them. They function well as it is, no need to define *yourself* how Java 8 works. – Yassine Badache Dec 18 '17 at 14:12
  • 4
    Thank you for your suggestions but inside my method I use ZoneDateTime.now() which is static method. I have to be sure that "now" points in particular moment in time. I don't think that wrapping ZoneDatetime.now() by another method is a good idea. Tests shouldn't impact on source code. I'm wondering why my static method from final class can be mocked and ZoneDateTime.now() can't. – bombel Dec 18 '17 at 14:59
  • This might be a more relevant duplicate: https://stackoverflow.com/questions/2001671/override-java-system-currenttimemillis-for-testing-time-sensitive-code – Sean Van Gorder Dec 18 '17 at 20:35

0 Answers0