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

Ran*_*ize 26 java junit calendar date mocking

在我的代码中,我有这样的事情:

private void doSomething() {
   Calendar today = Calendar.getInstance();
   ....
}
Run Code Online (Sandbox Code Playgroud)

如何在我的junit测试中"模拟"它以返回特定的日期?

GoG*_*ris 20

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

在课堂上:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassThatCallsTheCalendar.class})
Run Code Online (Sandbox Code Playgroud)

成功的关键是你必须将类放在PrepareForTest中使用Calendar而不是Calendar本身,因为它是一个系统类.(在我发现这个之前,我个人不得不经常搜索)

然后是嘲弄本身:

mockStatic(Calendar.class);
when(Calendar.getInstance()).thenReturn(calendar);
Run Code Online (Sandbox Code Playgroud)


BeR*_*ive 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()

  • Joda Time的`DateTimeUtils`类具有静态方法,用于设置所有其他Joda Time对象的当前时间.这对于将时间设置为某个时刻非常有用,例如用于测试. (4认同)

bla*_*ank 9

不要嘲笑它 - 而是引入一个你可以模拟得到日期的方法.像这样的东西:

interface Utility {

    Date getDate();
}

Utilities implements Utility {


    public Date getDate() {

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

}
Run Code Online (Sandbox Code Playgroud)

然后你可以将它注入到你的类中,或者只使用带有一堆静态方法的helper类和一个load方法:

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

}
Run Code Online (Sandbox Code Playgroud)

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

private void doSomething() {
   Date today = AppUtil.getDate();
   ....
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在测试方法中加载模拟接口.

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

     // .. set up your expectations

     // exercise the functionality
     classUnderTest.doSomethingViaAPI();

     // ... maybe assert something 

}
Run Code Online (Sandbox Code Playgroud)

另请参阅您是否只能模拟您拥有的类型?测试气味 - 一切都被嘲笑


Sur*_*kha 6

使用Mockito和PowerMockito:

Calendar endOfMarch = Calendar.getInstance();
endOfMarch.set(2011, Calendar.MARCH, 27);
PowerMockito.mockStatic(Calendar.class);
Mockito.when(Calendar.getInstance()).thenReturn(endOfMarch);
Run Code Online (Sandbox Code Playgroud)

有关完整代码,请参阅链接.