Стратегии издеваться над веб-сервисом - PullRequest
1 голос
/ 30 апреля 2009

Я внедряю клиента, использующего веб-сервис. Я хочу уменьшить зависимости и решил издеваться над веб-сервисом.
Я использую mockito , у него есть преимущество по сравнению с 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 . На мой взгляд, это слишком гранулировано.

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

Речь идет не о коде, а о подходе .

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

Ответы [ 3 ]

2 голосов
/ 02 июня 2009

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

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

private GeoLocationFactory(WebService service) {
   ...
}

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

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

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

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

1 голос
/ 27 января 2012

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

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

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

Пример кода можно найти здесь: Перемешивание .NET WebServices с Mockito

1 голос
/ 30 апреля 2009

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

...