Проблемы с Mocking класса итератора в Mockito - PullRequest
0 голосов
/ 11 июля 2019

Я пытаюсь смоделировать класс перехватчика SOAP, где один из методов класса возвращает объект Iterator. Однако после двойной проверки синтаксиса итератор не заменяется реальным итератором, и Mockito продолжает запускать метод без реального итератора.

Я пытался смоделировать возвращаемое значение перехватчика, используя различные методы mockito (doReturn, when ... thenReturn), и ни один из методов не работал. Я не уверен, где моя ошибка в моем насмешке.

Вот как я высмеиваю текущий объект в моем тестовом классе:

@Mock private WebServiceTemplate template;
@Mock private SoapInterceptor interceptor;
@Mock private Iterator<Attachment> iterator;

    @Test
    public void testGetDocsSoapClient() {
        @SuppressWarnings("unchecked")
        Iterator<Attachment> realIterator = new ArrayListIterator();
        ObjectFactory realFactory = new ObjectFactory();

        assertFalse(realIterator.hasNext());

        doReturn(realFactory.createAwsGetDocsRequest(createMockAwsGetDocsReq()))
            .when(factory).createAwsGetDocsRequest(any (AwsGetDocsRequest.class));
        doReturn(realFactory.createAwsGetDocsResponse(createAwsGetDocsResponse()))
            .when(template).marshalSendAndReceive(any(Object.class), any(SoapActionCallback.class));
        doReturn(realIterator)
            .when(interceptor).getSoapAttachments();

Вот как метод вызывается в реальном классе.

Iterator<Attachment> soapAttachments = attachmentInterceptor.getSoapAttachments();
ImageListDVO imgList = convertToImageList(soapAttachments);

... и мой тестовый пример завершается неудачно в последней строке этого частного метода.

private ImageListDVO convertToImageList(Iterator<Attachment> attachments) {
        ImageListDVO imgList = new ImageListDVO();

        while(attachments.hasNext()) {

Я должен правильно смоделировать объект, но я получаю исключение NullPointerException, которое указывает, что объект не смоделирован и не введен правильно.

1 Ответ

0 голосов
/ 12 июля 2019

Я думаю, что вы используете неправильный синтаксис. Если я правильно понимаю, вам нужно издеваться над SoapInterceptor, который имеет метод getSoapAttachments()

Для этого вам нужно изменить код на что-то вроде этого:

    @InjectMocks
    // the class under test should be put here

    @Mock
    SoapInterceptor attachmentInterceptor;

    @Test
    public void testGetDocsSoapClient() {

       // this is either a real interceptor or a mocked version of it
       Iterator<Attachment> iterator = ... ;
       when(attachmentInterceptor.getSoapAttachments()).thenReturn(iterator);
    }

Методы do обычно используются, когда вы хотите смоделировать пустые методы.

Вы также написали, что уже пробовали это, поэтому вполне вероятно, что вы неправильно инициализируете Mockito.


Убедитесь, что вы используете правильный Runner / Extension / Rule или что-либо еще (например, MockitoAnnotations.initMocks (testClass)). Существуют определенные различия между используемой версией JUnit. (Если вам все еще нужна помощь, предоставьте JUnit & Mockito Verison, который вы используете).

(см. https://static.javadoc.io/org.mockito/mockito-core/2.28.2/org/mockito/Mockito.html#9)


Еще одна возможность того, что вещи не вводятся, может заключаться в том, что ваш класс структурирован таким образом, что mockito не может его обработать.

Из вашего тестового примера я бы предположил, что вы использовали инжекцию поля, поэтому аннотированное поле @Mock должно иметь то же имя, что и поле private, которое есть в вашем классе тестирования. Итак, еще раз, я не уверен, какой из них вы не назвали.

Должна быть правильная аннотация @InjectMocks для этого класса, который вы используете, если только вы не предоставили Mocks вручную. (Но в этом случае вы, вероятно, не будете использовать аннотацию @Mock).



Изменить:
Другая интерпретация вашего вопроса может состоять в том, что вы пытаетесь протестировать метод самого SoapInterceptor и хотите заменить метод, который возвращает итератор, на что-то другое.

В этом случае вам следует вместо этого взглянуть на создание Spy, и ваш код должен выглядеть следующим образом:

    @Test
    public void testGetDocsSoapClient() {

        SoapInterceptor interceptor = new SoapInterceptor();
        SoapInterceptor spy = Mockito.spy(interceptor);

        when(spy.getSoapAttachments()).thenReturn(iterator);

        ...
    }
...