java: how to mock Calendar.getInstance()?

匿名 (未验证) 提交于 2019-12-03 01:49:02

问题:

In my code I have something like this:

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

How can I "mock" it in my junit test to return a specific date?

回答1:

As far as I see it you have three sensible options:

  1. Inject the Calendar instance in whatever method/class you set that day in.

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

  2. Use JodaTime instead of Calendar. This is less an option and more a case of a suggestion as JodaTime will make your life a lot easier. You will still need to inject this time in to the method.

    DateTime dt = new DateTime();

    Date jdkDate = dt.toDate();

  3. Wrap Calendar inside some interface that allows you to fetch the time. You then just mock that interface and get it to return a constant Date.

    Date today = calendarInterfaceInstance.getCurrentDate()



回答2:

Don't mock it - instead introduce a method you can mock that gets dates. Something like this:

interface Utility {      Date getDate(); }  Utilities implements Utility {       public Date getDate() {          return Calendar.getInstance().getTime();     }  } 

Then you can inject this into your class or just use a helper class with a bunch of static methods with a load method for the interface:

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

Then in your application code:

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

You can then just load a mock interface in your test methods.

@Test public void shouldDoSomethingUseful() {      Utility mockUtility = // .. create mock here      AppUtil.load(mockUtility);       // .. set up your expectations       // exercise the functionality      classUnderTest.doSomethingViaAPI();       // ... maybe assert something   } 

See also Should you only mock types you own? and Test smell - everything is mocked



回答3:

You can mock it using PowerMock in combination with Mockito:

On top of your class:

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

The key to success is that you have to put the class where you use Calendar in PrepareForTest instead of Calendar itself because it is a system class. (I personally had to search a lot before I found this)

Then the mocking itself:

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


回答4:

Using Mockito and PowerMockito:

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

Refer to the link for the complete code.



回答5:

Write a class called DateHelper with a method getCalendar that returns Calendar.getInstance(). Refactor the class that you're testing so that it has a member variable of type DateHelper, and a constructor that injects that member variable. Use that constructor in your test, to inject a mock of DateHelper, in which getCalendar has been stubbed to return some known date.



回答6:

You can mockit using JMockit. Here you can see how you can do it: Mock Java Calendar - JMockit vs Mockito.



回答7:

For those who follows MVP pattern mocking Calendar is a piece of cake:

  1. In a Presenter create a method which returns calendar instance:

     public Calendar getCurrentTime() {           return Calendar.getInstance();         } 
  2. In your view (Activity, Fragment etc) you access the calendar with help of presenter:

     Calendar calendar = mPresenter.getCurrentTime();     // do whatever you want 
  3. In your tests you do:

     // create a dummy calendar     Calendar mockCalendar = ...     // You've already mocked your Presenter, haven't you?     when(mMockPresenter.getCurrentTime()).thenReturn(mockCalendar);     // here you are! 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!