En un anterior serie de entradas de blog Expliqué cómo usar TestContainers para tus pruebas Junit de Java. Algunos de los temas que no abordamos fueron acerca de cómo probar N1QL, crear tus propios buckets, índice etc... Este post será sobre la construcción de... Spring Data Couchbase casos de prueba y cubrir esas cuestiones que dejamos fuera.
Puerto no configurable por cable
Una de las limitaciones que tenemos actualmente en Couchbase Server es que no se puede cambiar algunos de los puertos por defecto. Esto es un problema con Docker ya que es cambiar los puertos sólo se notifica lo contrario. Esto puede ser genial porque significa que puedes tener varias instancias de Couchbase corriendo en la misma máquina. Pero desafortunadamente no funcionará así que algunos puertos tendrán que ser arreglados. Esto puede ser declarado bastante fácilmente con TestContainers usando el método addFixedExposedPort.
1 2 3 4 5 6 7 8 9 10 |
@Anular protegido void configure() { addExposedPorts(8091, 11207, 11210, 11211, 18091, 18092, 18093); addFixedExposedPort(8092, 8092); addFixedExposedPort(8093, 8093); addFixedExposedPort(8094, 8094); addFixedExposedPort(8095, 8095); setWaitStrategy(nuevo HttpWaitStrategy().paraRuta("/ui/index.html#/")); } |
Con eso fuera del camino, nuestro Java SDK será capaz de conectarse a N1QL.
Caso de prueba abstracto de Spring Data Couchbase Docker
El objetivo aquí es crear un caso de prueba abstracto que será utilizado por cualquier clase que necesite una instancia de Couchbase y Spring Data Couchbase configurado. Se empieza como en los posts anteriores instanciando un campo CouchbaseContainer. Como estamos probando Spring Data configuramos el soporte para Index, Query y añadimos FTS para más adelante.
Para asegurarse de que esta clase ejecutará las pruebas de su aplicación, añada el parámetro @RunWith(SpringRunner.class)
anotación. Y para asegurarte de que la configuración de tu aplicación se prueba tan bien como nuestra configuración personalizada, añade @SpringBootTest(classes = {GittalentBackendApplication.class, AbstractSPDataTestConfig.CouchbaseTestConfig.class})
.
Ahora hablando de configuración personalizada, ¿qué necesitamos? Queremos anular la configuración por defecto de Couchbase de la aplicación. Para ello necesitamos implementar un CouchbaseConfigurer. Esta interfaz define todos los bean necesarios para que Spring Data Couchbase funcione correctamente. Proporciona instancias para CouchbaseEnvironment, ClusterInfo, Cluster y Bucket.
Todos ellos provendrán de nuestra configuración de CouchbaseContainer antes de ejecutar las pruebas. Así que tenemos que asegurarnos de que el Contenedor está funcionando y listo antes de inicializar todos los beans. Esto se puede conseguir añadiendo un método init() anotado con @PostConstruct. Esto nos permitirá primero asegurarnos de que el contenedor se está ejecutando, y luego configurar cosas adicionales. En el siguiente ejemplo configuramos un cubo llamado default y configuramos el tipo de índice para que sea MOI.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
@CorreCon(SpringRunner.clase) @SpringBootTest(clases = {GittalentBackendApplication.clase, AbstractSPDataTestConfig.CouchbaseTestConfig.clase}) público abstracto clase AbstractSPDataTestConfig { público estático final Cadena clusterUser = "Administrador"; público estático final Cadena clusterPassword = "contraseña"; @Regla de clase público estático CouchbaseContainer couchbaseContainer = nuevo CouchbaseContainer() .conFTS(verdadero) .withIndex(verdadero) .conQuery(verdadero) .withClusterUsername(clusterUser) .withClusterContraseña(clusterPassword); @Configuración estático clase CouchbaseTestConfig implementa CouchbaseConfigurer { privado CouchbaseContainer couchbaseContainer; @PostConstruir público void init() lanza Excepción { couchbaseContainer = AbstractSPDataTestConfig.couchbaseContainer; BucketSettings ajustes = DefaultBucketSettings.constructor() .enableFlush(verdadero).nombre("por defecto").cuota(100).réplicas(0).tipo(Tipo de cubo.SOPORTE).construya(); ajustes = couchbaseCluster().clusterManager(clusterUser, clusterPassword).insertarCubo(ajustes); couchbaseContainer.callCouchbaseRestAPI("/configuración/índices", "indexerThreads=0&logLevel=info&maxRollbackPoints=5&storageMode=memory_optimized", "Administrador", "contraseña"); waitForContainer(); } público void waitForContainer(){ CouchbaseWaitStrategy s = nuevo CouchbaseWaitStrategy(); s.withBasicCredentials(clusterUser, clusterPassword); s.waitUntilReady(couchbaseContainer); } @Anular @Judía público CouchbaseEnvironment couchbaseEnvironment() { devolver couchbaseContainer.getCouchbaseEnvironnement(); } @Anular @Judía público Grupo couchbaseCluster() lanza Excepción { devolver couchbaseContainer.geCouchbaseCluster(); } @Anular @Judía público ClusterInfo couchbaseClusterInfo() lanza Excepción { Grupo cc = couchbaseCluster(); ClusterManager director = cc.clusterManager(clusterUser, clusterPassword); devolver director.información(); } @Anular @Judía público Cubo couchbaseClient() lanza Excepción { devolver couchbaseContainer.geCouchbaseCluster().openBucket("por defecto"); } } } |
Una vez que tenemos este caso de prueba abstracto, todo lo que tenemos que hacer es crear una clase que lo extienda y empezar a escribir pruebas. Aquí podemos inyectar Servicios de nuestra aplicación así como un Bucket de nivel inferior. Lo que ves en este test es primero una llamada a un servicio importador que crea documentos. Luego creamos un índice en el bucket por defecto y probamos una consulta en él.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
público clase GitTalentGHImportTests extiende AbstractSPDataTestConfig { @Autowired privado GithubImportService githubImportService; @Autowired privado Cubo cubo; @Prueba público void importDevAdvocateTeam(){ githubImportService.importarUnDesarrollador("ldoguin"); N1qlQueryResultado resultado = cubo.consulta(N1qlQuery.simple("CREAR ÍNDICE PRIMARIO SOBRE default")); N1qlQuery consulta = N1qlQuery.simple("SELECT * FROM default WHERE developerInfo.username = 'ldoguin'"); resultado = cubo.consulta(consulta); N1qlQueryRow fila = resultado.filas().siguiente(); Afirme.assertNotNull(fila); } } |
Como se puede ver una vez creado el caso de prueba Abstracto, la cantidad de código es realmente mínima y corresponde exactamente a lo que se quiere probar.
[...] Laurent Doguin, defensor de los desarrolladores de Couchbase, ha elaborado un buen artículo sobre cómo probar aplicaciones Couchbase de Spring Data con contenedores de prueba y [...]
Hola,
Estoy teniendo problemas al hacer varios archivos que extienden la clase Abstract.
¿Puedes probar en tu lado? A ver si hay algo que estoy haciendo mal...
Gracias de antemano,
Saludos,