Marquis Blount Marquis Blount - 5 months ago 271
Java Question

Java PowerMockito Mocking Instant.now()

I'm attempting to Mock the static method

Instant.now()
and I continue to keep coming across weird behavior when trying to mock classes from
java.time
package. Please see my code below on attempting to mock
Instant.now()


@RunWith(PowerMockRunner.class)
@PrepareForTest(Instant.class)
public class UnitTestClasss {
@Test
public void unitTestMethod() throws Exception {
mockCurrentTimeAtMidNight();
instanceOfSystemUnderTest.someMethodDependingOnTime();
assertHandledHere();
}

/*See First Error Below */
private void mockCurrentTimeAtMidNight() {
ZonedDateTime current = ZonedDateTime.now();
ZonedDateTime mockMidNight = ZonedDateTime.of(current.getYear(), current.getMonthValue(),
current.getDayOfMonth(), 0, 0, 0, 0,current.getZone());

PowerMockito.mockStatic(Instant.class);
PowerMockito.when(Instant.now()).thenReturn(Instant.from(mockMidNight));
}

/*See Second Error Below */
private void mockCurrentTimeAtMidNight2() {
Calendar cal = Calendar.getInstance();

ZonedDateTime mockMidNight = ZonedDateTime.of(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0, 0,ZoneId.of("US/Eastern"));
Instant instant = mockMidNight.toInstant();
PowerMockito.mockStatic(Instant.class);
PowerMockito.when(Instant.now()).thenReturn(instant);
}

}



Errors 1
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:495)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed


Errors 2: with Reason: [source error]
toInstant()
not found in
java.time.ZonedDateTime


Answer

From what I was able to tell i was getting the error because originally I was calling .now() in my unit test then trying to mock it afterwards. The reason for this is because I thought i could have my test use the method unmocked then mock it so my SUT could then used the mocked form.

I ended up changing this a bit and mocked ZonedDateTime.ofInstant(obj,obj) instead. this is what I did

@Test
    public void renamingToArbitraryMethodName() throws Exception {
        ZonedDateTime current = ZonedDateTime.now();
        ZonedDateTime mockMidNight = ZonedDateTime.of(current.getYear(), current.getMonthValue(),
                                                      current.getDayOfMonth(), 0, 0, 0, 0, ZoneId.of("US/Eastern"));

        PowerMockito.mockStatic(ZonedDateTime.class);
        PowerMockito.when(ZonedDateTime.ofInstant(anyObject(), anyObject())).thenReturn(mockTime);
    }

In my scenario this worked for me because I was able to get away with my Test class using .now() while my source for SUT used .ofInstant(...).