java - tutorial - En una aplicación Apache Camel, ¿cómo pueden las pruebas unitarias inyectar puntos finales falsos en lugar de los reales?
junit java ejemplos (1)
Estoy implementando un patrón de traducción de mensajes con Apache Camel, para consumir mensajes desde un punto final RESTful y enviarlos a un punto final AMQP.
La aplicación adjunta está basada en Spring Boot, por lo que estoy usando el componente " spring-boot " de Camel para integrar los dos frameworks. Como lo sugiere la documentación en este enlace de primavera-inicio, estoy implementando mi ruta Camel dentro de una clase @Configuration
-annotated que extiende RouteBuilder
:
@Component
public class MyRestToAmqpRouter extends RouteBuilder {
@Override
public void configure() throws Exception {
from("jetty:http://my-restful-url")
.process(exchange -> {
// convert the message body from JSON to XML, take some
// incoming header values and put them in the outgoing
// body, etc...
}).to("rabbitmq://my-rabbitmq-url");
}
}
Mi pregunta es cómo hacer una prueba unitaria de esta traducción, sin necesitar un punto final RESTful real o un corredor RabbitMQ configurado. He leído muchos ejemplos en línea, así como el libro Camel in Action ... y parece que el enfoque típico para probar unidades en una ruta Camel es cortar y pegar la ruta en la prueba de la unidad, y reemplazar una o más URL de punto final con " mock:whatever
".
Supongo que eso funciona ... pero es terriblemente frágil, y su suite de pruebas no reconocerá cuando alguien más tarde cambie el código real sin actualizar la prueba unitaria.
He intentado adaptar algunos ejemplos de pruebas unitarias basadas en Spring con burlas, como esta:
@RunWith(CamelSpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Application.class})
public class MyRestToAmqpRouterTest extends AbstractJUnit4SpringContextTests {
@Produce(uri = "jetty:http://my-restful-url")
private ProducerTemplate fakeRest;
@EndpointInject(uri = "rabbitmq://my-rabbit-url")
private MockEndpoint fakeRabbit;
@Test
@DirtiesContext
public void testRouter() throws InterruptedException {
fakeRabbit.expectedMessageCount(1);
fakeRest.sendBodyAndHeader("", "header-1", "some value");
fakeRabbit.assertIsSatisfied();
}
}
Mi esperanza era que Camel tomaría esas URL de punto final de la prueba unitaria, las registraría como simulacros ... y luego usaría los simulacros en lugar del punto final real cuando el código real intentara usar esas URL.
Sin embargo, no estoy seguro de que esto sea posible. Cuando uso las URL reales en la prueba unitaria, recibo IllegalArgumentException
, porque aparentemente no se puede inyectar una URL de punto final "real" en una instancia de MockEndpoint
(solo las URL con el prefijo " mock:
").
Cuando uso una URL de punto final " mock:...
" en mi prueba de unidad, entonces es inútil porque no hay nada que la vincule a la URL de punto final real en la clase bajo prueba. De modo que esa URL de punto final real nunca se anula. Cuando se ejecuta el código real, simplemente usa el punto final real como es normal (y el objetivo es poder probar sin una dependencia externa en RabbitMQ).
¿Me estoy perdiendo algo en un nivel realmente fundamental aquí? Parece que habría una manera para que las pruebas unitarias inyecten rutas falsas en una clase como esta, de modo que el código bajo prueba pueda pasar de puntos finales reales a simulacros sin siquiera darse cuenta. Alternativamente, supongo que podría refactorizar mi código para que el Processor
anónimo se elevara a una clase independiente ... y luego podría probar su lógica de traducción independientemente de la ruta. Pero eso parece una prueba incompleta.
Algunos consejos de lo que puedes hacer.
Puede volver a leer el libro de Camel sobre pruebas y prestar atención al uso de consejos con
Y también hay mockEndpointsAndSkip
Y también puedes usar el componente stub
O use marcadores de posición de propiedad en sus rutas, y luego configure los uris para que sean falsos / stub, etc. para probarlos, y use los reales para producción