Вопрос

Я реализую клиента, использующего веб-сервис.Я хочу уменьшить зависимости и решил поиздеваться над веб-сервисом.
я использую мокито, он имеет преимущество передEasyMock, чтобы иметь возможность имитировать классы, а не только интерфейсы.Но дело не в этом.

В моем тесте у меня есть этот код:

// Mock the required objects
Document mDocument = mock(Document.class);
Element mRootElement = mock(Element.class);
Element mGeonameElement = mock(Element.class);
Element mLatElement = mock(Element.class);
Element mLonElement = mock(Element.class);

// record their behavior
when(mDocument.getRootElement()).thenReturn(mRootElement);
when(mRootElement.getChild("geoname")).thenReturn(mGeonameElement);
when(mGeonameElement.getChild("lat")).thenReturn(mLatElement);
when(mGeonameElement.getChild("lon")).thenReturn(mLonElement);
// A_LOCATION_BEAN is a simple pojo for lat & lon, don't care about it!
when(mLatElement.getText()).thenReturn(
    Float.toString(A_LOCATION_BEAN.getLat()));
when(mLonElement.getText()).thenReturn(
    Float.toString(A_LOCATION_BEAN.getLon()));

// let it work!
GeoLocationFetcher geoLocationFetcher = GeoLocationFetcher
    .getInstance();
LocationBean locationBean = geoLocationFetcher
    .extractGeoLocationFromXml(mDocument);

// verify their behavior
verify(mDocument).getRootElement();
verify(mRootElement).getChild("geoname");
verify(mGeonameElement).getChild("lat");
verify(mGeonameElement).getChild("lon");
verify(mLatElement).getText();
verify(mLonElement).getText();

assertEquals(A_LOCATION_BEAN, locationBean);

Мой код показывает, что я «микротестирую» объект-потребитель.Это как если бы я реализовал свой продуктивный код в своем тесте.Пример результата xml: Лондон на GeoNames.На мой взгляд, это слишком детализировано.

Но как я могу издеваться над веб-сервисом, не давая подробностей?Должен ли я позволить макетному объекту просто возвращать XML-файл?

Дело не в коде, а в подход.

Я использую JUnit 4.x и Mockito 1.7.

Это было полезно?

Решение

вы действительно хотите имитировать результаты, возвращаемые веб-сервисом, в коде, который будет использовать результат.В приведенном выше примере кода вы, похоже, издеваетесь над mDocument, но на самом деле вы хотите передать экземпляр mDocument, который был возвращен из имитируемого экземпляра вашего веб-сервиса, и утверждать, что locationBean, возвращенный из geoLocationFetcher, соответствует значению A_LOCATION_BEAN.

Другие советы

Я думаю, что настоящая проблема здесь в том, что у вас есть синглтон, который вызывает и создает веб-сервис, поэтому трудно вставить макет.

Возможно, вам придется добавить (возможно, на уровне пакета) доступ к классу Singleton.Например, если конструктор выглядит примерно так

private GeoLocationFactory(WebService service) {
   ...
}

вы можете создать уровень пакета конструктора и просто создать его с помощью имитируемого веб-сервиса.

В качестве альтернативы вы можете настроить веб-сервис, добавив метод установки, хотя мне не нравятся изменяемые синглтоны.Также в этом случае вам необходимо не забыть впоследствии отключить веб-сервис.

Если веб-сервис создается в методе, вам, возможно, придется сделать GeoLocationFactory расширяемым, чтобы заменить фиктивную службу.

Вы также можете рассмотреть возможность удаления самого синглтона.В Интернете и, возможно, здесь есть статьи о том, как это сделать.

Самый простой вариант — издеваться над клиентом WebService,

when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
    .thenReturn("<location/>");

Вы можете изменить код для чтения XML-ответа из файловой системы.

Пример кода можно найти здесь: Издевательство над веб-сервисами .NET с помощью Mockito

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top