如何使用 Mockito 在 Java 中模拟 new Date()

问题描述:

我有一个函数可以使用当前时间进行一些计算.我想用 mockito 来模拟它.

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;
    }
}

我想要类似的东西:

@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.

正确的做法是重构您的代码,使其更易于测试,如下所示.重构您的代码以消除对 Date 的直接依赖将允许您为正常运行时和测试运行时注入不同的实现:

The right thing to do is to restructure your code to make it more testable as shown below. Restructuring your code to remove the direct dependency on Date will allow you to inject different implementations for normal runtime and test runtime:

interface DateTime {
    Date getDate();
}

class DateTimeImpl implements DateTime {
    @Override
    public Date getDate() {
       return new Date();
    }
}

class MyClass {

    private final DateTime dateTime;
    // inject your Mock DateTime when testing other wise inject DateTimeImpl

    public MyClass(final DateTime dateTime) {
        this.dateTime = dateTime;
    }

    public long getDoubleTime(){
        return dateTime.getDate().getTime()*2;
    }
}

public class MyClassTest {
    private MyClass myClassTest;

    @Before
    public void setUp() {
        final Date date = Mockito.mock(Date.class);
        Mockito.when(date.getTime()).thenReturn(30L);

        final DateTime dt = Mockito.mock(DateTime.class);
        Mockito.when(dt.getDate()).thenReturn(date);

        myClassTest = new MyClass(dt);
    }

    @Test
    public void someTest() {
        final long doubleTime = myClassTest.getDoubleTime();
        assertEquals(60, doubleTime);
    }
}