How to mock new Date() in java using Mockito

Viewed 125314

I have a function that uses the current time to make some calculations. I'd like to mock it using mockito.

An example of the class I'd like to test:

public class ClassToTest {
    public long getDoubleTime(){
        return new Date().getTime()*2;
    }
}

I'd like something like:

@Test
public void testDoubleTime(){
   mockDateSomeHow(Date.class).when(getTime()).return(30);
   assertEquals(60,new ClassToTest().getDoubleTime());
}

Is it possible to mock that? I wouldn't like to change the "tested" code in order to be tested.

7 Answers

you can also use jmockit to mock new Date():

    @Test
    public void mockTime() {
        new MockUp<System>() {
            @Mock
            public long currentTimeMillis() {
                // Now is always 11/11/2021
                Date fake = new Date(121, Calendar.DECEMBER, 11);
                return fake.getTime();
            }
        };
        Assert.assertEquals("mock time failed", new Date(121, Calendar.DECEMBER, 11), new Date());
    }

Working example with new Date() and System.currentTimeMillis() using PowerMockito.
Here is an example for Instance.

@RunWith(PowerMockRunner.class)
@PrepareForTest(LegacyClass.class) // prepares byte-code of the LegacyClass
public class SystemTimeTest {
    
    private final Date fakeNow = Date.from(Instant.parse("2010-12-03T10:15:30.00Z"));

    @Before
    public void init() throws Exception {
        // mock new Date()
        PowerMockito.whenNew(Date.class).withNoArguments().thenReturn(fakeNow);
        System.out.println("Fake now: " + fakeNow);

        // mock System.currentTimeMillis()
        PowerMockito.mockStatic(System.class);
        PowerMockito.when(System.currentTimeMillis()).thenReturn(fakeNow.getTime());
        System.out.println("Fake currentTimeMillis: " + System.currentTimeMillis());
    }

    @Test
    public void legacyClass() {
        LegacyClass legacyClass = new LegacyClass();
        legacyClass.methodWithNewDate();
        legacyClass.methodWithCurrentTimeMillis();
    }

}

class LegacyClass {

    public void methodWithNewDate() {
        Date now = new Date();
        System.out.println("LegacyClass new Date() is " + now);
    }

    public void methodWithCurrentTimeMillis() {
        long now = System.currentTimeMillis();
        System.out.println("LegacyClass System.currentTimeMillis() is " + now);
    }

}

Console output

Fake now: Fri Dec 03 16:15:30 NOVT 2010
Fake currentTimeMillis: 1291371330000
LegacyClass new Date() is Fri Dec 03 16:15:30 NOVT 2010
LegacyClass System.currentTimeMillis() is 1291371330000
Related