Pergunta

Estou implementando um cliente consumir um webservice. Quero reduzir dependências e decidiu zombar do webservice.
Eu uso Mockito , ele tem a vantagem vs. EasyMock para ser capaz de aulas simuladas, não interfaces de apenas. Mas isso não é o ponto.

No meu teste, eu tenho este código:

// 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);

O que meus programas de código é que eu "micro-test" o objeto de consumo. É como se eu iria implementar meu código produtivo no meu teste. Um exemplo para o xml resultado é Londres em GeoNames . Na minha opinião, é muito granular.

Mas como posso zombar um webservice sem dar everystep? Devo deixar o objeto fictício apenas retornar um arquivo XML?

Não é sobre o código, mas a abordagem .

Eu estou usando JUnit 4.x e Mockito 1.7

Foi útil?

Solução

Você realmente quer ser zombando os resultados retornados a partir do webservice para o código que estará usando o resultado. Em seu código exemplo acima você parece estar zombando mDocument mas você realmente quer passar em uma instância do mDocument que foi retornado de uma instância zombou de seu webservice e afirmar que o locationBean retornado do geoLocationFetcher corresponde ao valor de A_LOCATION_BEAN.

Outras dicas

Eu acho que o verdadeiro problema aqui é que você tem um singleton que as chamadas e cria o serviço web por isso é difícil para inserir um simulada.

Você pode ter que adicionar (possivelmente nível pacote) acesso à classe Singleton. Por exemplo, se o construtor é algo como

private GeoLocationFactory(WebService service) {
   ...
}

Você pode fazer a nível de pacote construtor e apenas criar um com um serviço web zombou.

Como alternativa, você pode definir o webservice, adicionando um método setter, embora eu não gosto Singletons mutáveis. Também nesse caso, você tem que lembrar para remover o webservice depois.

Se o webservice é criado em um método que você pode ter que fazer o extensível GeoLocationFactory para substituir o serviço de simulação.

Você também pode olhar para remover o próprio singleton. Há artigos on-line e provavelmente aqui sobre como fazer isso.

A opção mais fácil seria zombar do cliente WebService,

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

Você pode modificar o código para ler o XML de resposta do sistema de arquivos.

O código de exemplo pode ser encontrado aqui: Mocking .NET WebServices com Mockito

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top