En mi carrera pasada, a menudo descubrí que algunas personas no escribían el código de prueba, y la razón por la que afirmaron no escribir fue que no podían escribir fácilmente casos de prueba que cubrieran múltiples módulos diferentes. Bueno, creo que la mayoría de ellos carecen de algunos medios técnicos más fáciles de maestro o no tienen tiempo para resolverlo. Después de todo, siempre habrá varias presiones, como el progreso en el trabajo. Debido a que no sé cómo probar, a menudo ignoro las pruebas de integración, y los problemas provocados están empeorando el software, más y más errores y más clientes decepcionados. Así que quiero compartir algunas experiencias personales para presentar el misterio de las pruebas de integración.
Cómo integrar mejor las pruebas de proyectos basados en primavera <Br /> Uso de herramientas: Spring, Junit, Mockito
Imagine que hay un proyecto de primavera que integra algunos servicios externos, como algunos servicios web bancarios. Luego, los problemas encontrados al escribir casos de prueba para este proyecto y completar estas pruebas en un sistema de integración continua son básicamente los mismos:
1. Habrá transacciones en cada prueba, y cada transacción requiere un costo monetario, que finalmente será asumido por el cliente;
2. Las solicitudes excesivas emitidas durante las pruebas pueden considerarse solicitudes maliciosas, lo que puede hacer que la cuenta en el banco esté bloqueada, con la consecuencia de la falla de la prueba;
3. Cuando la prueba se realiza utilizando un entorno de no producción, los resultados de la prueba no son muy confiables. Del mismo modo, la consecuencia es que la prueba falla.
Por lo general, cuando prueba una sola clase, el problema es fácil de resolver porque puede virtualizar algunos servicios externos para llamar. Pero al probar todo el gran proceso comercial, significa que necesita probar múltiples componentes, y en este momento, debe incorporar estos componentes en el contenedor de primavera para la administración. Afortunadamente, Spring incluye un marco de prueba muy excelente que le permite inyectar frijoles de los archivos de configuración del entorno de producción en el entorno de prueba, pero para los llamados servicios externos, necesitamos escribir implementaciones simuladas nosotros mismos. La primera reacción de las personas comunes puede ser reinyectar (modificar) los frijoles inyectados por primavera durante la etapa de configuración de la prueba, pero este método debe considerarse cuidadosamente.
Advertencia: de esta manera, su código de prueba rompe el comportamiento del contenedor, por lo que no hay garantía de que sea lo mismo que los resultados de su prueba en un entorno real.
De hecho, en lugar de implementar la clase simulada primero y luego reinyectarla en el frijol requerido, podemos dejar que Spring nos ayude a inyectar la clase simulada desde el principio. Demostremos con código.
El proyecto de muestra contiene una clase llamada BankService, que representa la llamada al servicio externo, y una clase llamada UserBalanceservice, que llama a BankService. UserBalancesService se implementa muy simple, solo para completar la conversión del equilibrio de cadena a tipo doble.
Código fuente de BankService.java:
interfaz pública BankService {String getBalanceByEmail (correo electrónico de cadena);} Código fuente de BankServiceImpl.java:
La clase pública BankServiceImpl implementa BankService {@Override public String getBalanceByEmail (Correo electrónico de cadena) {lanzar una nueva Operación UnpportedOxception ("Operación fallida debido a una excepción externa"); }} Código fuente de userbalanceservice.java:
interfaz userbalanceservice {double getAcCountBalance (correo electrónico de cadena);} Código fuente de UserBalancesServiceImpl.java:
clase pública UserBalancesServiceImpl implementa UserBalancesService {@aUtowired privado bankservice bankService; @Override public Double GetAcCountBalance (correo electrónico de cadena) {return double.ValueOf (bankService.getBalanceByEmail (correo electrónico)); }} Luego está el archivo de configuración XML de Spring, agregando la declaración de frijol requerida.
Código fuente de ApplicationContext.xml:
<? xml versión = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" "" "" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beanss.xsd"> <bean id = "bankservice"/> <bean id = "usalancesservice"/> <</> </</> </</beay
Aquí está el código fuente de la clase de prueba UserBalancesServiceImpltest.java:
@RunWith (SpringJunit4ClassRunner.class) @ContextConfiguration (ubicaciones = "classpath: /springtest/springockito/applicationContext.xml") Class pública UserBalancesServiceImplProfileTest {@autowed WalancessBalancesservice UserBalancesService; @AUTOWIREDIRD BankService BankService; @Test public void debería reembolsar a la basura () {doble balance = userBalanceservice.getAccountBalance ("[email protected]"); afirmarequals (saldo, doble.valueOf (123.45d)); }} Como esperábamos, el método de prueba informa una excepción no compatible de OperationException. Nuestro propósito actual es reemplazar BankService con nuestra implementación de simulación. Está bien usar Mockito directamente para generar frijoles de fábrica, pero hay una mejor opción, use el marco Springockito. Puedes tener una idea aproximada antes de continuar.
La pregunta restante es simple: cómo inyectar resorte en un frijol simulado en lugar de un frijol real, no había otra forma antes de la primavera 3.1, excepto para crear un nuevo archivo de configuración XML. Pero desde que Spring introdujo la definición de perfil de frijoles, tenemos una solución más elegante, aunque este enfoque también requiere un archivo de configuración XML adicional específicamente para las pruebas. Aquí está el código para el archivo de configuración testApplicationContext.xml utilizado para probar:
<? xml versión = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" "" "" xmlns: mockito = "http://www.mockito.org/spring/mockito" xsi: schemalocation = "http://www.springframework.org/schema/beans htp://www.springframework.org/schema/sepring-beats.xssping-beats http://www.mockito.org/spring/mockito https://bitbucket.org/kubek2k/springockito/raw/tip/springockito/src/main/resources/spring/mockito.xsd "> <import resource = "classpath: /springtest/springockito/applicationContext.xml"/> <beans perfil = "springtest"> <mockito: mock id = "bankservice"/> </ beans> </beans>
El código fuente de la clase de prueba UserBalancesServiceImplProfileTest.java después de hacer las modificaciones correspondientes:
@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (ubicaciones = "classpath: /springTest/springockito/testapplicationContext.xml")@ActiveProfiles (Profiles = {"SpringTest"}) Public UserBalanceserServiceImplProfilEtest {@@AutoWowered Sprofiles private UserBalutes @AUTOWIREDIRD BankService BankService; @Bebore public void setup () lanza la excepción {Mockito.When (bankService.getBalanceByEmail ("[email protected]")). Luego, Return (String.ValueOf (123.45d)); } @Test public void debería reembolsar a la voluntad () {doble balance = userBalancesService.getAccountBalance ("[email protected]"); afirmarequals (saldo, doble.valueOf (123.45d)); }} Es posible que haya notado que en el método de configuración, definimos el comportamiento simulado y agregamos la anotación @profile a la clase. Esta anotación activa un perfil llamado SpringTest, por lo que el frijol simulado con Springockito se puede inyectar automáticamente en cualquier lugar que necesite. El resultado de ejecución de esta prueba será exitoso porque Spring inyecta la versión simulada por Springockito, no la versión declarada en ApplicationContext.xml.
Continuar optimizando nuestras pruebas
Si podemos llevar la solución a este problema, este artículo no parecerá ser defectuoso. Springockito ofrece otro nombre llamado
Marco de anotación de Springockito , que nos permite usar anotaciones en las clases de prueba para inyectar clases simuladas. Antes de continuar leyendo, es mejor ir al sitio web para echar un vistazo. Ok, aquí está el código de prueba modificado.
Código de origen de UserBalancesServiceImplannotationTest.java: @runwith (SpringJUnit4ClassRunner.class) @ContextConfiguration (loader = SpringOckitOcontextLoader.class, localizaciones = "classpath: /SpringTest/SSPRINGOCKITO/AppicationContext.xml") @AUTOWIREDEDIRDIREDURACIÓN PRIVADOSEBSERVICE USERBALANSEVICE; @AUtowired @replaceWithMock Private BankService BankService; @Bebore public void setup () lanza la excepción {Mockito.When (bankService.getBalanceByEmail ("[email protected]")). Luego, Return (String.ValueOf (valorf (123.45d))); } @Test public void debería reembolsar a la voluntad () {doble balance = userBalancesService.getAccountBalance ("[email protected]"); afirmarequals (saldo, valor de (123.45d)); }} Tenga en cuenta que no hay un archivo de configuración XML recientemente introducido aquí, pero el ApplicationContext.xml del entorno formal se usa directamente. Utilizamos la anotación @replaceWithMock para marcar el bankservice de banket de tipo, y luego definimos el comportamiento de la clase simulada en el método de configuración.
posdata
El proyecto Springockito-Annotations tiene una gran ventaja, es decir, crea nuestro código de prueba en la cobertura de dependencia, para que no necesitemos definir archivos de configuración XML adicionales o modificar los archivos de configuración del entorno de producción para las pruebas. Si no se usan las anotaciones Springockito, no tenemos más remedio que definir archivos de configuración XML adicionales. Por lo tanto, recomiendo que use las anotaciones Springockito en sus pruebas de integración para que pueda minimizar el impacto de sus casos de prueba en su código de producción, y también eliminar la carga de mantener archivos de configuración XML adicionales.
Posdata
Escribir pruebas de integración para proyectos de primavera es realmente mucho más fácil. El código en el artículo se refiere a mi propio GitHub.
Enlace de traducción: http://www.codeceo.com/article/spring-test-is-easy.html
Inglés original: Prueba si puedes #1 (marco de primavera)
Traductor: sandbox wang, red de codificación
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.