java:如何模拟Calendar.getInstance()?

时间:2012-02-14 11:10:45

标签: java date junit calendar mocking

在我的代码中,我有类似的东西:

private void doSomething() {
   Calendar today = Calendar.getInstance();
   ....
}

如何在junit测试中“模拟”它以返回特定日期?

6 个答案:

答案 0 :(得分:19)

你可以使用PowerMock和Mockito一起模拟它:

在班上:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassThatCallsTheCalendar.class})

成功的关键在于您必须将类放在PrepareForTest中使用Calendar而不是Calendar本身,因为它是一个系统类。 (在我发现之前,我个人不得不进行大量搜索)

然后嘲笑自己:

mockStatic(Calendar.class);
when(Calendar.getInstance()).thenReturn(calendar);

答案 1 :(得分:17)

据我所知,你有三个合理的选择:

  1. 在您当天设置的任何方法/类中注入Calendar实例。

    private void method(final Calendar cal) { Date today = cal.getTime(); }

  2. 使用JodaTime代替Calendar。这不是一个选择,而是一个建议的案例,因为JodaTime将使您的生活更轻松。您仍然需要将此时间注入方法。

    DateTime dt = new DateTime();

    Date jdkDate = dt.toDate();

  3. 在一些允许您获取时间的界面中包裹Calendar。然后,您只需模拟该接口并使其返回常量Date

    Date today = calendarInterfaceInstance.getCurrentDate()

答案 2 :(得分:9)

不要嘲笑它 - 而是引入一种可以模拟获取日期的方法。像这样:

interface Utility {

    Date getDate();
}

Utilities implements Utility {


    public Date getDate() {

        return Calendar.getInstance().getTime();
    }

}

然后你可以将它注入到你的类中,或者只使用带有一堆静态方法的辅助类和一个用于接口的加载方法:

public class AppUtil {

    private static Utility util = new Utilities();

    public static void load(Utility newUtil) {

         this.util = newUtil;
    }

    public static Date getDate() {

        return util.getDate();
    }

}

然后在您的应用程序代码中:

private void doSomething() {
   Date today = AppUtil.getDate();
   ....
}

然后,您可以在测试方法中加载模拟界面。

@Test
public void shouldDoSomethingUseful() {
     Utility mockUtility = // .. create mock here
     AppUtil.load(mockUtility);

     // .. set up your expectations

     // exercise the functionality
     classUnderTest.doSomethingViaAPI();

     // ... maybe assert something 

}

另请参阅Should you only mock types you own?Test smell - everything is mocked

答案 3 :(得分:6)

使用Mockito和PowerMockito:

Calendar endOfMarch = Calendar.getInstance();
endOfMarch.set(2011, Calendar.MARCH, 27);
PowerMockito.mockStatic(Calendar.class);
Mockito.when(Calendar.getInstance()).thenReturn(endOfMarch);

有关完整代码,请参阅link

答案 4 :(得分:2)

使用返回DateHelper的方法getCalendar编写一个名为Calendar.getInstance()的类。重构您正在测试的类,使其具有类型DateHelper的成员变量,以及注入该成员变量的构造函数。在测试中使用该构造函数,以注入DateHelper的模拟,其中getCalendar已被存根以返回某个已知日期。

答案 5 :(得分:1)

您可以使用JMockit进行模拟。在这里,您可以看到如何做到这一点:Mock Java Calendar - JMockit vs Mockito