Ява PowerMockito Насмешливый Мгновение.сейчас()


Я пытаюсь издеваться над статическим методом Instant.now() и продолжаю сталкиваться со странным поведением при попытке издеваться над классами из пакета java.time. Пожалуйста, смотрите мой код ниже о попытке издеваться Instant.now()

@RunWith(PowerMockRunner.class)
@PrepareForTest(Instant.class)
public class UnitTestClasss {
    @Test
    public void unitTestMethod() throws Exception {
        mockCurrentTimeAtMidNight();
        instanceOfSystemUnderTest.someMethodDependingOnTime();
        assertHandledHere();
    }

    /*See First Error Below */
    private void mockCurrentTimeAtMidNight() {
        ZonedDateTime current = ZonedDateTime.now();
        ZonedDateTime mockMidNight = ZonedDateTime.of(current.getYear(), current.getMonthValue(),
                current.getDayOfMonth(), 0, 0, 0, 0,current.getZone());

        PowerMockito.mockStatic(Instant.class);
        PowerMockito.when(Instant.now()).thenReturn(Instant.from(mockMidNight));
    }

    /*See Second Error Below */
    private void mockCurrentTimeAtMidNight2() {
        Calendar cal = Calendar.getInstance();

        ZonedDateTime mockMidNight = ZonedDateTime.of(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
                cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0, 0,ZoneId.of("US/Eastern"));
        Instant instant = mockMidNight.toInstant();
        PowerMockito.mockStatic(Instant.class);
        PowerMockito.when(Instant.now()).thenReturn(instant);
    }

}

Ошибки 1 орг..мокито.исключения.неправильное использование.UnfinishedStubbingException: Незаконченное раскорчевки обнаружить здесь: - >в орг.powermock.прикладной программный интерфейс.мокито.PowerMockito.когда(PowerMockito.java:495)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, you naughty developer!
 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed

Ошибки 2: с причиной: [ошибка источника] toInstant() нет найдено в java.time.ZonedDateTime

2 3

2 ответа:

Вы пытаетесь издеваться над классом java.time, что означает, что вы пытаетесь издеваться над системным классом. Это требует, чтобы вы поместили свою собственную систему под тест в аннотации @ PrepareForTest , потому что PowerMock не может перехватить загрузку вызываемого класса, поэтому он должен перехватить загрузку вашего класса вместо этого и сделать его байт-код-перезапись там.

(это не совсем совпадает с вашим сообщением об ошибке, но все равно будет очень ясной причиной, почему у вас возникли проблемы здесь этого не будет с несистемными классами в Mockito и PowerMock.)

Опасности издевательств над системными классами-помимо того, что вы издеваетесь над объектами данных, и особенно над объектами, которые имеют явные функции модульного теста (такие как переопределение часов Энди Тернера, упомянутое в комментариях)-являются отличной причинойне использовать здесь mocks.

Из того, что я смог сказать, я получал ошибку, потому что первоначально я звонил .теперь() в моем модульном тесте, а затем пытается издеваться над ним позже. Причина этого заключается в том, что я думал, что мой тест может использовать метод unmocked, а затем издеваться над ним, чтобы мой SUT мог использовать издевательскую форму.

В итоге я немного изменил это и вместо этого высмеял ZonedDateTime.ofInstant(obj,obj). вот что я сделал

@Test
    public void renamingToArbitraryMethodName() throws Exception {
        ZonedDateTime current = ZonedDateTime.now();
        ZonedDateTime mockMidNight = ZonedDateTime.of(current.getYear(), current.getMonthValue(),
                                                      current.getDayOfMonth(), 0, 0, 0, 0, ZoneId.of("US/Eastern"));

        PowerMockito.mockStatic(ZonedDateTime.class);
        PowerMockito.when(ZonedDateTime.ofInstant(anyObject(), anyObject())).thenReturn(mockTime);
    }

В моем сценарии это сработало для меня, потому что я смог уйти с моим тестовым классом, используя .now() в то время как мой источник для SUT используется .ofInstant(...).