Anotaciones de Spring: Pruebas

    Introducci贸n

    Spring Framework es un marco muy robusto, lanzado en 2002. Sus caracter铆sticas principales se pueden aplicar a aplicaciones Java simples o ampliarse a aplicaciones web modernas y complejas.

    Dado que se actualiza constantemente y sigue nuevos paradigmas de arquitectura y programaci贸n, ofrece soporte para muchos otros marcos que trabajan de la mano con 茅l.

    Con una gama tan amplia de funcionalidades, es normal que nos presente algunas anotaciones nuevas, que son una parte clave del desarrollo de aplicaciones Spring.

    La configuraci贸n de Spring es totalmente personalizable, lo que originalmente se hizo a trav茅s de archivos de configuraci贸n XML. Sin embargo, este enfoque se ha vuelto obsoleto y la mayor铆a de las personas hoy en d铆a recurren a la configuraci贸n de anotaciones.

    Dicho esto, esta serie de art铆culos tiene como objetivo desentra帽ar las opciones que usted, como desarrollador, tiene para configurar y usar el marco Spring:

    • Anotaciones de Spring: @RequestMapping y sus variantes
    • Spring Annotations: anotaciones de Core Framework
    • Notas de Spring: Spring Cloud
    • Spring Annotations: Prueba de anotaciones

    Anotaciones de prueba de Spring

    El desarrollo basado en pruebas (TDD) se ha convertido en un tema importante hoy en d铆a y se considera una pr谩ctica extremadamente mala no probar correctamente sus aplicaciones.

    Hay varios marcos de trabajo ampliamente utilizados que facilitan mucho este trabajo a los desarrolladores, donde JUnit es el m谩s utilizado.

    Para ponerse al d铆a con las pr谩cticas de programaci贸n modernas, Spring ha lanzado una nueva starterdependencia spring-boot-starter-test, que consta de algunos marcos:

    • JUnit
    • Prueba de Spring y prueba de arranque de Spring
    • AssertJ
    • Hamcrest
    • Mockito
    • JSONassert
    • JsonPath

    En este art铆culo, cubriremos las siguientes anotaciones de prueba:

    • @BootstrapCon
    • @ContextConfiguration
    • @WebAppConfiguration
    • @ContextHierarchy
    • @ActiveProfiles
    • @Retroceder
    • @Cometer
    • @AntesTransacciones
    • @Despu茅s de la transacci贸n
    • @Sql
    • @SqlGrupo
    • @SqlConfig
    • @SpringBootTest
    • @DataJpaTest
    • @DataMongoTest
    • @WebMvcTest
    • @MockBean
    • @AutoConfigureMockMvc
    • @JsonTest
    • @TestPropertySource
    • @Con tiempo
    • @Repetir

    @BootstrapCon

    La @BootstrapWithanotaci贸n es una anotaci贸n que probablemente utilizar谩 muy raramente. Las configuraciones predeterminadas para Spring TestContext Framework son m谩s que suficientes para la mayor铆a de los casos de uso.

    Si no es as铆, puede cambiar ContextLoadero implementar TestContexts personalizados entre una gran cantidad de otras configuraciones que puede cambiar.

    Nuevamente, esta es una anotaci贸n que probablemente no usar谩 si no es parte de un equipo que realmente necesita una configuraci贸n personalizada para Spring TestContext Framework.

    @ContextConfiguration

    Una @ContextConfigurationanotaci贸n de prueba de integraci贸n aplicada a nivel de clase que se usa para definir c贸mo Spring debe cargar el ApplicationContext.

    Esta anotaci贸n se puede aplicar junto con el @Component(as铆 como las anotaciones tales como @Service, @Repository, etc.) y @Configurationanotaciones as铆 como cualquier clase que contiene @Beans.

    Puede utilizar la anotaci贸n para hacer referencia a archivos XML o clases Java:

    @ContextConfiguration("/some-test-configuration-file.xml")
    // @ContetConfiguration(locations = "/some-test-configuration-file.xml")
    // You can use the optional `locations` flag as well.
    public class ApplicationTests {
        // Testing code...
    }
    
    @ContextConfiguration(classes = TestConfiguration.class)
    public class ApplicationTests {
        // Testing code...
    }
    

    Por ejemplo, digamos que tenemos TestBean:

    @Configuration
    public class TestBean {
    
        @Bean
        public DeveloperService developerService() {
            return new DeveloperService();
        }
    }
    

    Si quisi茅ramos hacer algunos asserts en este bean, har铆amos algo como:

    @ContextConfiguration(classes = TestBean.class)
    public class ApplicationTests {
        @Autowired
        private DeveloperService;
    
        @Test
        public void testBean() {
            Developer dev = developerService.getDeveloperById(5);
            assertEquals("David", dev.getName());
        }
    }
    

    Hoy en d铆a, es preferible confiar en el enfoque de clase, ya que XML generalmente se considera un enfoque desactualizado para registrar beans. Si tiene m谩s de una clase, por supuesto, simplemente las especificar铆a a trav茅s de classes = {TestBean.class, TestBean2.class, TestBean3.class}, etc.

    Esto nos lleva a la @Testanotaci贸n, que se tratar谩 en detalle a continuaci贸n. Por ahora, us茅moslo simplemente con fines ilustrativos.

    @WebAppConfiguration

    Si desea asegurarse de que Spring cargue una WebApplicationContextpara sus pruebas en lugar de la normal ApplicationContext, puede usar la @WebAppConfigurationanotaci贸n junto con la @ContextConfigurationanotaci贸n:

    @ContextConfiguration(classes = TestBean.class)
    @WebAppConfiguration
    public class ApplicationTests {
    
        @Autowired
        private DeveloperService;
    
        // Rest of the code...
    }
    

    Alternativamente, puede especificar la valuebandera, o m谩s bien, la ubicaci贸n del WebApplicationContext, si no se encuentra en el src/main/webappdirectorio predeterminado :

    @WebAppConfiguration("some/other/location")
    public class ApplicationTests {}
    

    @ContextHierarchy

    Otra anotaci贸n que generalmente se usa con poca frecuencia (personalmente no he visto a nadie usarla en un proyecto) es la @ContextHierarchyanotaci贸n.

    Permite al desarrollador definir m煤ltiples @ContextConfigurations en niveles a trav茅s de una relaci贸n padre-hijo.

    La idea es que los contextos secundarios puedan usar los beans registrados en los contextos principales y esto mejora la reutilizaci贸n de los beans:

    @ContextHierarchy({
        @ContextConfiguration(classes = ApplicationTestConfiguration.class),
        @ContextConfiguration(classes = WebApplicationTestConfiguration.class)
    })
    public class ApplicationTests {
    
    }
    

    Si desea leer m谩s sobre esta anotaci贸n, la documentaci贸n contiene informaci贸n detallada sobre la jerarqu铆a de contexto.

    @ActiveProfiles

    La @ActiveProfilesanotaci贸n es una anotaci贸n bastante sencilla y sencilla. Define qu茅 perfil debe estar activo al cargar la configuraci贸n de contexto:

    @ContextConfiguration
    @ActiveProfiles("dev")
    public class ApplicationTests {}
    

    Esto indica que el perfil “dev” debe estar activo.

    El nombre de la anotaci贸n implica que podemos definir m煤ltiples perfiles, que podemos:

    @ContextConfiguration
    @ActiveProfiles({"dev", "prod"})
    public class ApplicationTests {}
    

    Si desea leer m谩s sobre Spring Profiles, 隆lo tenemos cubierto!

    @Rollback

    A veces, cuando se trata de bases de datos, queremos revertir los cambios que hemos realizado, especialmente si hemos provocado una excepci贸n.

    La @Rollbackanotaci贸n define si la transacci贸n de un m茅todo marcado con @Transactionaldebe revertirse una vez que se haya completado la llamada al m茅todo de prueba.

    Se puede aplicar a nivel de clase y m茅todo:

    • Nivel de clase : define la reversi贸n predeterminada para todos los m茅todos de prueba dentro de la clase.
    • Nivel de m茅todo : define la reversi贸n para el m茅todo de prueba espec铆fico
    @Rollback(true)
    @Test
    public void someTest() {
        // ...calling some transactional method
    }
    

    Una vez realizada la prueba, se revertir谩n todos los cambios realizados por el m茅todo transaccional.

    Un punto interesante a destacar es el hecho de que puede establecer el indicador opcional en false, en el que Spring garantiza que los cambios no se reviertan. Establecer la @Rollbackanotaci贸n en falsese comportar谩 exactamente igual que @Commit.

    @Commit

    Como anexo a la secci贸n anterior, la @Commitanotaci贸n se usa cuando queremos asegurar los cambios en la base de datos despu茅s de ejecutar los m茅todos de prueba.

    Se comporta igual que @Rollback(false)y se puede aplicar a nivel de clase o m茅todo:

    @Commit
    @Test
    public void someTest() {
        // ...calling some transactional method
    }
    

    @BeforeTransaction

    A veces, queremos ejecutar piezas de c贸digo espec铆ficas antes de realizar las transacciones. Para hacerlo, obviamente necesitamos definir m茅todos escritos espec铆ficamente para esto.

    Para invocarlos antes de cada transacci贸n, simplemente los anotamos con la @BeforeTransactionanotaci贸n:

    @BeforeTransaction
    void methodBeforeTransaction() {
        // ...ran before a transaction
    }
    

    Para que la anotaci贸n funcione correctamente, debe marcar sus m茅todos transaccionales con @Transactional.

    Nota : A partir de Spring 4.3, no es necesario que estos m茅todos sean p煤blicos.

    @AfterTransaction

    Con la misma naturaleza que la @BeforeTransactionanotaci贸n, la @AfterTransactionanotaci贸n ejecuta un m茅todo determinado despu茅s de que se ha realizado una transacci贸n:

    @AfterTransaction
    void methodAfterTransaction() {
        // ...ran after a transaction
    }
    

    Nota : A partir de Spring 4.3, no es necesario que estos m茅todos sean p煤blicos.

    @Sql

    Usando la @Sqlanotaci贸n y pasando el nombre (s) de los esquemas que deseamos que se ejecuten, podemos ejecutar mediante programaci贸n (o declarativamente) scripts SQL.

    De forma predeterminada, estos scripts se ejecutan antes que cualquier @Beforem茅todo.

    Si definimos un script, como createTable.sql:

    CREATE TABLE ITEM (ITEM_ID INT PRIMARY KEY, ITEM_NAME VARCHAR(256) NOT NULL);
    

    Podemos referenciarlo y ejecutarlo f谩cilmente:

    @Test
    @Sql("/createTable.sql")
    public void itemTest {
        // ...some code that depends on the sql script above
    }
    

    @SqlGroup

    La @SqlGroupanotaci贸n nos permite agrupar varios scripts SQL y ejecutarlos.

    Si tenemos otro script, como uno para eliminar la misma tabla dropTable.sql,:

    DROP TABLE ITEM;
    

    Podemos agrupar el createTable.sqlscript con el dropTable.sqlscript para ejecutar antes y despu茅s del m茅todo de prueba, por ejemplo:

    @Test
    @SqlGroup({
        @Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = ""),
        @Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD, scripts = ""),
    })
    public void itemTest {
        // ...item table gets created, tested by the code and then dropped
    }
    

    @SqlConfig

    Como su nombre lo indica, siguiendo los ejemplos de anotaciones est谩ndar de Spring, la @SqlConfiganotaci贸n se usa para definir la configuraci贸n de los scripts SQL: c贸mo se analizan y ejecutan.

    Se puede aplicar a nivel de clase o de m茅todo. Las pruebas de integraci贸n, que requieren una configuraci贸n global para todos los scripts SQL en ejecuci贸n, generalmente usan el enfoque a nivel de clase, mientras que el enfoque a nivel de m茅todo es para configuraciones locales de ciertos m茅todos:

    @Test
    @Sql(scripts = "/createTable.sql",
        config = @SqlConfig(attribute = "val", attribute2 = "val"))
    public void itemTest {
        // Some code...
    }
    

    Hay 9 atributos que puede pasar a la @SqlConfiganotaci贸n:

    • blockCommentEndDelimiter: Delimitador final para comentarios de bloque
    • blockCommentStartDelimiter: Delimitador de inicio para comentarios de bloque
    • commentPrefix: El prefijo para comentarios de una sola l铆nea
    • dataSource: Nombre del dataSourcefrijol
    • encoding: Especificando la codificaci贸n de los scripts
    • errorMode: Qu茅 modo usar cuando se encuentra un error
    • separator: El car谩cter que se usa para separar declaraciones
    • transactionManager: Nombre del bean administrador de transacciones
    • transactionMode: Qu茅 modo usar al ejecutar scripts SQL

    @SpringBootTest

    La @SpringBootTestanotaci贸n busca la clase de prueba anotada con la @SpringBootConfigurationque en la mayor铆a de los casos es nuestra clase de aplicaci贸n principal, ya que @SpringBootApplicationincluye la anotaci贸n anterior dentro de s铆 misma.

    Una vez encontrado, construye el contexto de la aplicaci贸n para el entorno de prueba. Incluso puede iniciar un entorno web utilizando el webEnvironmentatributo:

    @SpringBootTest
    public class IntegrationTests {
        // Rest of the code
    }
    
    @SpringBootTest(webEnvironment = pringBootTest.WebEnvironment.RANDOM_PORT)
    public class WebEnvIntegrationTests {
        // Rest of the code
    }
    

    @DataJpaTest

    Usando la @DataJpaTestanotaci贸n, podemos probar aplicaciones JPA. Se aplica a nivel de clase y construye un contexto de aplicaci贸n para todas las @Enitityclases, junto con una base de datos incorporada que se aplica de forma predeterminada.

    Nota : Las @Componentclases regulares no se cargan en el contexto de la aplicaci贸n creado por la @DataJpaTestanotaci贸n.

    Se utiliza junto con la @RunWith(SpringRunner.class)anotaci贸n, que indica qu茅 instalaciones utilizar谩 la clase marcada.

    De forma predeterminada, todas las transacciones JPA se revertir谩n (puede cambiar este comportamiento aplicando @Rollback(false)o @Commit):

    @RunWith(SpringRunner.class)
    @DataJpaTest
    public class SomeJpaTest {
        // Rest of the code
    }
    

    Sin embargo, esta es una prueba cl谩sica de JPA, si desea utilizar la base de datos real, en lugar de la base de datos incorporada en la memoria proporcionada, simplemente puede agregar otra anotaci贸n para evitar tal comportamiento:

    @RunWith(SpringRunner.class)
    @DataJpaTest
    @AutoConfigureTestDatabase(replace = Replace.NONE)
    public class SomeJpaTest {
        // Rest of the code
    }
    

    @DataMongoTest

    Muy similar a la @DataJpaTestanotaci贸n, para realizar pruebas cl谩sicas de MongoDB, aplicamos la @DataMongoTestanotaci贸n junto con la @RunWith(SpringRunner.class)anotaci贸n.

    Tenga en cuenta que esta anotaci贸n se usa cuando la prueba se aplica solo para probar componentes de MongoDB y agrega solo @Documentclases al contexto de la aplicaci贸n:

    @RunWith(SpringRunner.class)
    @DataMongoTest
    public class SomeMongoTest {
        // Rest of the code
    }
    

    Por otra parte, si desea ejecutar esto con la base de datos real, y no con la base de datos incrustada en memoria proporcionada por Mongo, puede excluir esta opci贸n:

    @RunWith(SpringRunner.class)
    @DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
    public class SomeMongoTest {
        // Rest of the code
    }
    

    @WebMvcTest

    Una vez m谩s, muy similar a la @DataJpaTesty las @DataMongoTestanotaciones, para llevar a cabo pruebas cl谩sicas Spring MVC, aplicamos la @WebMvcTestanotaci贸n junto a la @RunWith(SpringRunner.class)anotaci贸n.

    Tenga en cuenta que los efectos de esta anotaci贸n solo se aplican a la infraestructura MVC. Dicho esto, no crea una instancia de todo el contexto.

    La anotaci贸n se puede usar para probar un solo controlador, pas谩ndolo como un atributo como @WebMvcTest(SomeController.class).

    Para crear una instancia de otras dependencias necesarias, como los servicios, normalmente usamos la @MockBeananotaci贸n. @WebMvcTestConfigura MockMvcque se puede usar para probar f谩cil y r谩pidamente los controladores MVC y crear instancias de otros colaboradores:

    @RunWith(SpringRunner.class)
    @WebMvcTest(HomeController.class)
    public class ControllerTests {
    
        // Auto-configured to make mocking easier
        @Autowired
        private MockMvc mockMvc;
    
        @MockBean
        private SomeBean someBean;
    
        @Test
        public void someTest() {
            // Test logic
        }
    }
    

    @MockBean

    Al probar unidades espec铆ficas, como por ejemplo, un controlador, queremos aislarlas tanto como podamos. Dado que la mayor铆a de los componentes de la aplicaci贸n Spring dependen de muchos otros componentes (dependencias), es esencial asegurarse de que todos estos componentes se puedan probar individualmente.

    Para aislar con 茅xito los objetos que queremos probar, sin dejar de permitir que la aplicaci贸n funcione bien, simulamos o simulamos las dependencias. Se @MockBeanusa una anotaci贸n cuando queremos simular una dependencia en una aplicaci贸n:

    @RunWith(SpringRunner.class)
    @WebMvcTest(HomeController.class)
    public class ControllerTests {
    
        // Auto-configured to make mocking easier
        @Autowired
        private MockMvc mockMvc;
    
        @MockBean
        private SomeBean someBean;
    
        @Test
        public void someTest() {
            // Test logic
        }
    }
    

    En este ejemplo, la someBeandependencia simula una dependencia real. Si el bean existe en el contexto, el simulacro lo reemplaza. Si no existe, el simulacro se agrega al contexto como un bean.

    Nota : hay una diferencia entre las anotaciones @Mocky @MockBean. La @Mockanotaci贸n proviene de la biblioteca Mockito y es equivalente a llamar al Mockito.mock()m茅todo. Por otro lado, @MockBeanes el contenedor de la biblioteca Spring de la @Mockanotaci贸n.

    @AutoConfigureMockMvc

    Como sugiere el nombre, la @AutoConfigureMockMvcanotaci贸n, cuando se aplica a una clase de prueba, se configurar谩 autom谩ticamente MockMvc, de la misma manera que @WebMvcTestla configurar谩 autom谩ticamente.

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class ControllerTests {
    
        @Autowired
        private MockMvc mockMvc;
    
        // Rest of the logic
    }
    

    Si desea enfocarse solo en la capa web, considere usar la @WebMvcTestanotaci贸n en su lugar.

    @JsonTest

    Muchas aplicaciones se ocupan de la serializaci贸n / deserializaci贸n de JSON. Por lo tanto, tiene mucho sentido asegurarse de que funcione correctamente mientras se prueba la aplicaci贸n. Al usar la @JsonTestanotaci贸n, Spring configura autom谩ticamente el mapeador JSON compatible (Jackson, Gson o Jsonb).

    Por lo general, se usa junto con @RunWith(SpringRunner.class)y se usa para pruebas JSON cl谩sicas, buscando @JsonComponents.

    @RunWith(SpringRunner.class)
    @JsonTest
    public class JsonTests {
        @Test
        public void someJsonTest() {
            // Rest of the logic
        }
    }
    

    @TestPropertySource

    La @TestPropertySourceanotaci贸n se aplica a nivel de clase y define las ubicaciones de las fuentes de propiedad que queremos usar para la prueba.

    Estas propiedades se guardan como un conjunto de @PropertySources en el entorno del contexto de la aplicaci贸n. Estas propiedades tienen prioridad sobre las propiedades del sistema o de la aplicaci贸n.

    Esencialmente, cuando deseamos anular las propiedades del sistema / aplicaci贸n con propiedades espec铆ficas para nuestras pruebas, simplemente anotamos la clase de prueba:

    @RunWith(SpringRunner.class)
    @ContextConfiguration(classes = TestConfiguration.class)
    @TestPropertySource("classpath:applicationtest.properties")
    public class ApplicationTest {
        // Rest of the logic
    }
    

    Por otro lado, puede especificar propiedades en l铆nea, en lugar de todo el archivo de propiedades:

    @RunWith(SpringRunner.class)
    @ContextConfiguration(classes = TestConfiguration.class)
    @TestPropertySource(properties = {"sa.website_name = Pharos.sh", "sa.website_url = www.Pharos.sh.com"})
    public class ApplicationTest {
        // Rest of the logic
    }
    

    @Timed

    La @Timedanotaci贸n define el tiempo en milisegundos en el que el m茅todo de prueba debe finalizar la ejecuci贸n; de lo contrario, fallar谩:

    @Timed(millis = 1000)
    public void testMethod() {
        // Some test logic
    }
    

    Si la prueba tarda m谩s de un segundo en ejecutarse, fallar谩. Esto incluye todas las repeticiones del m茅todo, si la @Repeatanotaci贸n est谩 presente.

    @Repeat

    La @Repeatanotaci贸n define cu谩ntas veces se debe repetir un m茅todo de prueba:

    @Repeat(5)
    @Test
    public void testMethod() {
        // Some test logic
    }
    

    Esta prueba se repetir谩 cinco veces.

    Conclusi贸n

    El marco Spring es un marco poderoso y robusto que realmente cambi贸 el juego cuando se trata de desarrollar aplicaciones web. Entre todas las cosas que admite, ofrece un excelente soporte TDD para Spring Applications y permite a los desarrolladores configurar f谩cil y r谩pidamente cualquier tipo de pruebas.

    .

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *