java:如何模拟Calendar.getInstance()?
在我的代码中我有这样的事情:
private void doSomething() { Calendar today = Calendar.getInstance(); .... }
如何在我的junit测试中“模拟”它以返回特定的日期?
据我所知,你有三个合理的选择:
-
在您当天设置的任何方法/类中注入
Calendar
实例。private void method(final Calendar cal) { Date today = cal.getTime(); }
-
使用JodaTime而不是
Calendar
。 这不是一个选择,而是一个建议的案例,因为JodaTime将使您的生活更轻松。 您仍然需要将此时间注入方法。DateTime dt = new DateTime();
Date jdkDate = dt.toDate();
-
在一些允许您获取时间的界面中包装
Calendar
。 然后,您只需模拟该接口并使其返回一个常量Date
。Date today = calendarInterfaceInstance.getCurrentDate()
你可以使用PowerMock和Mockito一起模拟它:
在课堂上:
@RunWith(PowerMockRunner.class) @PrepareForTest({ClassThatCallsTheCalendar.class})
成功的关键是你必须将类放在PrepareForTest中使用Calendar而不是Calendar本身,因为它是一个系统类。 (在我发现这个之前,我个人不得不经常搜索)
然后嘲笑自己:
mockStatic(Calendar.class); when(Calendar.getInstance()).thenReturn(calendar);
不要嘲笑它 – 而是引入一个你可以模拟得到日期的方法。 像这样的东西:
interface Utility { Date getDate(); } Utilities implements Utility { public Date getDate() { return Calendar.getInstance().getTime(); } }
然后你可以将它注入到你的类中,或者只使用带有一堆静态方法的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(); } }
然后在您的应用程序代码:
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 }
另请参阅您是否只能模拟您拥有的类型? 和测试气味 – 一切都被嘲笑
使用Mockito和PowerMockito:
Calendar endOfMarch = Calendar.getInstance(); endOfMarch.set(2011, Calendar.MARCH, 27); PowerMockito.mockStatic(Calendar.class); Mockito.when(Calendar.getInstance()).thenReturn(endOfMarch);
有关完整代码,请参阅链接 。
使用返回Calendar.getInstance()
DateHelper
方法编写一个名为DateHelper
的类。 重构您正在测试的类,使其具有DateHelper
类型的成员变量,以及注入该成员变量的构造函数。 在测试中使用该构造函数,以注入DateHelper
的模拟,其中DateHelper
已被存根以返回某个已知日期。
你可以使用JMockit进行模拟。 在这里,您可以看到如何做到这一点: 模拟Java日历 – JMockit与Mockito 。
对于那些遵循MVP模式的人来说,日历是小菜一碟:
-
在Presenter中创建一个返回日历实例的方法:
public Calendar getCurrentTime() { return Calendar.getInstance(); }
-
在您的视图(活动,片段等)中,您可以在演示者的帮助下访问日历:
Calendar calendar = mPresenter.getCurrentTime(); // do whatever you want
-
在您的测试中,您可以:
// create a dummy calendar Calendar mockCalendar = ... // You've already mocked your Presenter, haven't you? when(mMockPresenter.getCurrentTime()).thenReturn(mockCalendar); // here you are!