2010-10-04 16 views
5

Digamos que estoy escribiendo una aplicación y que tienen que ser capaces de hacer algo como esto:https simulacros solicitan en Java

String url = "https://someurl/"; 
GetMethod method = new GetMethod(URLEncoder.encode(url)); 
String content = method.getResponseBodyAsString(); 

¿Hay una manera de proporcionar un servidor maqueta que dejarme manejar la https solicitud? Lo que estoy buscando es una forma de escribir pruebas unitarias, pero necesito poder burlarme de la parte que realmente sale a https://someurl para poder recuperar una respuesta conocida.

+0

duplicado Posible de http://stackoverflow.com/q/393099/2093341 – Andrea

Respuesta

3

esencialmente tiene dos opciones:

1. Resumen de la llamada al marco y probar esto.

E.g. refactorice el código para permitirle inyectar una implementación simulada en algún momento. Hay muchas maneras de hacer esto. p.ej. crea un getUrlAsString() y simula eso. (también se sugiere arriba). O crea una fábrica de obtención de URL que devuelve un objeto GetMethod. La fábrica entonces puede ser burlada.

2. Inicie un servidor de aplicaciones como parte de la prueba y luego ejecute el método en su contra. (Esto será más una prueba de integración)

Esto se puede lograr de varias maneras. Esto puede ser externo a la prueba, p. el plugin maven embarcadero. o la prueba puede iniciar el servidor mediante programación. ver: http://docs.codehaus.org/display/JETTY/Embedding+Jetty

Ejecutarlo a través de https complicará esto, pero aún será posible con certificados autofirmados. Pero me preguntaría, ¿qué es exactamente lo que quieres probar? Dudo que realmente necesites probar la funcionalidad de https, es una tecnología comprobada.

Personalmente, optaría por la opción 1: está intentando probar la funcionalidad de una biblioteca externa. Eso usualmente es innecesario. También es una buena práctica resumir sus dependencias a bibliotecas externas.

Espero que esto ayude.

1

Tome un vistazo a JWebUnit http://jwebunit.sourceforge.net/

He aquí un ejemplo de una prueba ... Es realmente bastante intuitiva.

public class ExampleWebTestCase extends WebTestCase { 
    public void setUp() { 
     super.setUp(); 
     setBaseUrl("http://localhost:8080/test"); 
    } 

    public void test1() { 
     beginAt("/home"); 
     clickLink("login"); 
     assertTitleEquals("Login"); 
     setTextField("username", "test"); 
     setTextField("password", "test123"); 
     submit(); 
     assertTitleEquals("Welcome, test!"); 
    } 
} 
+0

Sí, estoy familiarizado con JWebUnit, pero aquí tengo que ser capaz de burlarse de la URL real que se sirve arriba. JWebUnit funciona cuando el sitio/servicio web que está llamando se está ejecutando realmente. – dcp

1

Siempre se puede poner en marcha un servidor thttpd como parte de su unidad de prueba para servir las peticiones de forma local. Aunque, idealmente, tiene una bien probada GetMethod, y luego puede simplemente burlarse de ella, y no tener que tener realmente un servidor remoto para TODAS sus pruebas.

Recursos

1

Usted puede envolver el código de alguna clase y tienen WebClient.getUrl() y luego burlarse (por ejemplo jmock) que el método para volver los archivos almacenados - decir

expectation { 
    oneOf("https://someurl/"), will(returnValue(someHTML)); 
} 
2

Si está escribiendo una prueba de unidad, no lo hace y cualquier dependencia externa. de la API,

GetMethod 

extiende

HttpMethod 

por lo que pueden burlarse fácilmente con su biblioteca de burla preferido. Su

method.getResponseBodyAsString() 

llamada puede ser burlada para devolver todos los datos que desee.

+0

Pero GetMethod se está creando en el código en sí, no en mi prueba de unidad, por lo que no puedo simularlo. – dcp

+0

No entiendo, ¿no controlas el código que estás probando? – hvgotcodes

+0

Controlo el código, pero el objeto GetMethod se está creando dentro del método que estoy probando, por lo que no puedo pasar un objeto simulado. La forma en que funciona un simulacro es que lo configura de antemano y lo pasa al método que está probando, pero en este caso, el objeto GetMethod se está creando dentro del método mismo, por lo que no puedo pasarlo. Si es no está claro, házmelo saber. – dcp

1

hasta qué punto está usted interesado en burlarse de esta "Obtener" llamada, porque si usted está buscando un general propósito de burlarse del marco para Java que se integra bien con JUnit y permite configurar las expectativas que se afirman automáticamente cuando se incorporan en una suite JUnit, entonces realmente debería echar un vistazo a jMock.

Ahora sin más código, es difícil determinar si esto es realmente lo que busca, sino una (algo inútil) ejemplo de algo similar al código de ejemplo que escribió, sería algo como esto:

class GetMethodTest { 
@Rule public JUnitRuleMockery context = new JunitRuleMockery(); 

@Test 
public void testGetMethod() throws Exception { 
    // Setup mocked object with expectations 
    final GetMethod method = context.mock(GetMethod.class); 
    context.checking(new Expectations() {{ 
     oneOf (method).getResponseBodyAsString(); 
     will(returnValue("Response text goes here")); 
    }}); 

    // Now do the checking against mocked object 
    String content = method.getResponseBodyAsString(); 
} 
} 
+0

Realmente no funcionará en mi caso, vea mis comentarios a hvgotcodes. – dcp

+0

Hmm, entonces podría considerar usar un framework de extensión Java como Object Teams, que es capaz de redirigir llamadas a métodos específicos a sus propios métodos definidos, así puede acceder al punto preciso del flujo de control que necesita alterar, inyectar ya sea tu propio código o tu objeto burlado. No importa si se trata de un método público o privado, ObjecTeams actúa como un superconjunto a Java, por lo que puede hacer cosas que Java normalmente no podría hacer. – micdah

4

Eche un vistazo a jadler (http://jadler.net), una biblioteca http stubbing/mocking en la que he estado trabajando durante un tiempo. La versión estable 1.0.0 se ha acaba de publicar, se debe proporcionar las capacidades requeridos:

@Test 
public void getAccount() { 

    onRequest() 
     .havingMethodEqualTo("GET") 
     .havingURIEqualTo("/accounts/1") 
     .havingBody(isEmptyOrNullString()) 
     .havingHeaderEqualTo("Accept", "application/json") 
    .respond() 
     .withTimeout(2, SECONDS) 
     .withStatus(200) 
     .withBody("{\"account\":{\"id\" : 1}}") 
     .withEncoding(Charset.forName("UTF-8")) 
     .withContentType("application/json; charset=UTF-8"); 

    final AccountService service = new AccountServiceRestImpl("http", "localhost", port()); 
    final Account account = service.getAccount(1); 

    assertThat(account, is(notNullValue())); 
    assertThat(account.getId(), is(1)); 
} 


@Test 
public void deleteAccount() { 

    onRequest() 
     .havingMethodEqualTo("DELETE") 
     .havingPathEqualTo("/accounts/1") 
    .respond() 
     .withStatus(204); 

    final AccountService service = new AccountServiceRestImpl("http", "localhost", port()); 
    service.deleteAccount(1); 

    verifyThatRequest() 
     .havingMethodEqualTo("DELETE") 
     .havingPathEqualTo("/accounts/1") 
    .receivedOnce(); 
} 
Cuestiones relacionadas