unitarias unit test restassured pruebas mvc java unit-testing junit jersey jax-rs

java - unit - ¿Cómo puedo probar el código de unidad que llama a la API del cliente de Jersey?



spring boot unit test rest controller (3)

Por lo general, lo que realmente busca es "la forma en que utilizo el DSL del cliente de Jersey produce una solicitud a la URL correcta con la carga útil correcta y los parámetros de la URL" . Probar esto con Mockito es realmente detallado y el código de configuración generalmente terminará buscando algo como esto:

when(authentication.queryParam(eq("sa"), anyBoolean())).thenReturn(testAuthentication); when(testAuthentication.resolveTemplate("channel", "smf")).thenReturn(testAuthentication); when(testAuthentication.request( MediaType.APPLICATION_JSON_TYPE)).thenReturn(mockRequestBuilder); when(mockRequestBuilder.post(any(Entity.class))).thenReturn(mockResponse); when(mockResponse.readEntity(ResponseWrapper.class)).thenReturn(successfulAuthResponse());

Y esto es básicamente para una sola solicitud REST. Es demasiado detallado y, en lugar de probar el resultado esperado, simplemente está replicando los pasos que cree que son correctos al usar el DSL de Jersey Client.

En lugar de lo anterior, me gustaría burlarme de un servicio simple. Para esto, he utilizado WireMock que inicia un servidor Jetty y donde puedo apilar cosas como "esperar una solicitud a esta URL, responder con este mensaje y verificar que la carga útil es esta" .

Sé que esto se está imponiendo en una prueba de integración y es un poco más lento que solo usar Mockito, pero valoro las pruebas del resultado real y valoro la legibilidad de las pruebas mucho más en este caso.

La configuración de una prueba de cliente de Jersey basada en WireMock se ve algo así:

@Test public void exactUrlOnly() { stubFor(get(urlEqualTo("/some/thing")) .willReturn(aResponse() .withHeader("Content-Type", "text/plain") .withBody("Hello world!"))); assertThat(testClient.get("/some/thing").statusCode(), is(200)); assertThat(testClient.get("/some/thing/else").statusCode(), is(404)); }

Escribí un código que llama a la API del cliente de Jersey que a su vez llama a un servicio web que está fuera de mi control. No quiero que mi prueba de unidad llame al servicio web real.

¿Cuál es el mejor enfoque para escribir una prueba de unidad para el código que llama a la API del cliente de Jersey? ¿Debo usar la API del servidor de Jersey para escribir un servicio web JAX-RS y luego usar el Marco de prueba de Jersey para la prueba de la unidad? ¿O debería burlarme de las llamadas de servicio web de Jersey? Tengo acceso a JMock. ¿O debería intentar otro enfoque?

Durante mi investigación, encontré esta discusión describiendo varias opciones, pero encontré una solución completa. ¿Hay ejemplos de código disponibles que muestren un enfoque JUnit sugerido? No pude encontrar ninguna en la documentación de Jersey.

Aquí está el código fuente relevante:

public String getResult(URI uri) throws Exception { // error handling code removed for clarity ClientConfig clientConfig = new DefaultClientConfig(); Client client = Client.create(clientConfig); WebResource service = client.resource(uri); String result = service.accept(accept).get(String.class); return result; }

Aquí hay ejemplos de código de prueba que me gustaría pasar. Me gustaría probar (1) pasar una URI válida y obtener una cadena válida de vuelta y (2) pasar una URI no válida (por cualquier razón, inaccesible o no autorizada) y volver a obtener una excepción.

@Test public void testGetResult_ValidUri() throws Exception { String xml = retriever.getResult(VALID_URI); Assert.assertFalse(StringUtils.isBlank(xml)); } @Test(expected = IllegalArgumentException.class) public void testGetResult_InvalidUri() throws Exception { retriever.getResult(INVALID_URI); }

Todo lo anterior es la descripción simple de lo que hace mi código. En realidad, hay una capa encima de eso que acepta dos URI, primero intenta llamar al primer URI, y si ese URI falla, entonces intenta llamar al segundo URI. Me gustaría que las pruebas unitarias que cubren (1) la primera URI tenga éxito, (2) la primera URI falle y la segunda URI tenga éxito, y (3) ambas URI falle. Este código es lo suficientemente complejo como para que pueda probar estos diferentes escenarios utilizando JUnit, pero para hacer esto, necesito ejecutar servicios web stand-in reales o simular las llamadas a la API del cliente de Jersey.


Simplemente implemente un servicio similar al trabajo y en su configuración de prueba unitaria inicie el servicio utilizando HttpServerFactory.


Trate de usar Mockito o Easymock para las llamadas de servicio de burla. Solo debes burlarte de estos métodos que realmente se utilizan, sin necesidad de burlarte de todos los métodos. Puede crear un objeto simulado para la clase WebResource, y luego simular aceptar el método de llamada.

En el método de prueba @ BeforeClass / @ Before JUnit escribe algo como (ejemplo de Mockito)

WebResource res = mock(WebResource.class); when(res.accept(something)).thenReturn(thatWhatYouWant);

Luego, en sus pruebas, puede usar el objeto res como si fuera un objeto real y llamar a un método simulado. En lugar de devolver el valor también puede lanzar excepciones. Mockito está muy bien.