Подтвердить что ты не робот

Java: как насмехаться Calendar.getInstance()?

В моем коде у меня есть что-то вроде этого:

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

Как я могу "высмеять" его в своем тесте junit, чтобы вернуть конкретную дату?

4b9b3361

Ответ 1

Насколько я понимаю, у вас есть три разумных варианта:

  • Внесите экземпляр 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()

Ответ 2

Не издевайтесь над этим - вместо этого введите метод, который вы можете издеваться над датами. Что-то вроде этого:

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 

}

См. также Если вы только издеваетесь над типами, которыми владеете? и Проверить запах - все издевается

Ответ 3

Вы можете издеваться над ним с помощью PowerMock в сочетании с Mockito:

В верхней части вашего класса:

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

Ключом к успеху является то, что вы должны поместить класс, в котором вы используете Calendar в PrepareForTest, вместо самого Календаря, потому что это системный класс. (Мне лично пришлось много искать, прежде чем я нашел это)

Затем насмехается:

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

Ответ 4

Использование Mockito и PowerMockito:

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

Обратитесь к ссылке для полного кода.

Ответ 5

Напишите класс под названием DateHelper с помощью метода getCalendar, который возвращает Calendar.getInstance(). Рефакторируйте класс, который вы тестируете, чтобы он имел переменную-член типа DateHelper и конструктор, который вводит эту переменную-член. Используйте этот конструктор в своем тесте, чтобы ввести макет DateHelper, в котором getCalendar был заглушен, чтобы вернуть известную дату.

Ответ 6

Вы можете издеваться, используя JMockit. Здесь вы можете увидеть, как вы можете это сделать: Mock Java Calendar - JMockit vs Mockito.

Ответ 7

Для тех, кто следует шаблону MVP, насмешливый календарь - это кусок торта:

  • В презентаторе создайте метод, который возвращает экземпляр календаря:

     public Calendar getCurrentTime() {  
            return Calendar.getInstance();    
        }
    
  • В вашем представлении (Activity, Fragment и т.д.) вы получаете доступ к календарю с помощью ведущего:

     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!