Em um anterior série de postagens em blogs Expliquei como usar TestContainers para seus testes Java Junit. Algumas das questões que não abordamos foram sobre como testar o N1QL, criar seus próprios buckets, índices etc... Esta postagem será sobre a criação de Dados do Spring Couchbase casos de teste e cobrir essas questões que deixamos de lado.
Porta não configurável de fio rígido
Uma das limitações que temos atualmente no Couchbase Server é que você não pode alterar algumas das portas padrão. Esse é um problema com o Docker, pois a alteração das portas é apenas notificada de outra forma. Isso pode ser ótimo porque significa que você pode ter várias instâncias do Couchbase em execução na mesma máquina. Mas, infelizmente, não funcionará, portanto, algumas portas terão de ser corrigidas. Isso pode ser declarado com bastante facilidade com TestContainers usando o método addFixedExposedPort.
|
1 2 3 4 5 6 7 8 9 10 |
@Override protected void configure() { addExposedPorts(8091, 11207, 11210, 11211, 18091, 18092, 18093); addFixedExposedPort(8092, 8092); addFixedExposedPort(8093, 8093); addFixedExposedPort(8094, 8094); addFixedExposedPort(8095, 8095); setWaitStrategy(new HttpWaitStrategy().forPath("/ui/index.html#/")); } |
Com isso resolvido, nosso Java SDK poderá se conectar ao N1QL.
Caso de teste abstrato do Spring Data Couchbase Docker
O objetivo aqui é criar um caso de teste abstrato que será usado por qualquer classe que precise de uma instância do Couchbase e do Spring Data Couchbase configurado. Ele começa como nos posts anteriores, instanciando um campo CouchbaseContainer. Como estamos testando o Spring Data, configuramos o suporte para Index, Query e vamos incluir o FTS para mais tarde.
Para garantir que essa classe executará testes para seu aplicativo, adicione o parâmetro @RunWith(SpringRunner.class) annotation. E para garantir que a configuração do seu aplicativo seja testada, assim como a nossa configuração personalizada, adicione @SpringBootTest(classes = {GittalentBackendApplication.class, AbstractSPDataTestConfig.CouchbaseTestConfig.class}).
Agora, falando sobre configuração personalizada, do que precisamos? Queremos substituir a configuração padrão do Couchbase do aplicativo. Para isso, precisamos implementar um CouchbaseConfigurer. Essa interface define todo o bean necessário para que o Spring Data Couchbase funcione corretamente. Ela fornece instâncias para CouchbaseEnvironment, ClusterInfo, Cluster e Bucket.
Todos eles virão de nossa configuração do CouchbaseContainer antes da execução dos testes. Portanto, precisamos nos certificar de que o contêiner esteja em execução e pronto antes de inicializar todos os beans. Isso pode ser feito adicionando um método init() anotado com @PostConstruct. Isso nos permitirá primeiro garantir que o contêiner esteja em execução e, em seguida, configurar outras coisas. No exemplo a seguir, configuramos um bucket chamado default e configuramos o tipo de índice como 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 |
@RunWith(SpringRunner.class) @SpringBootTest(classes = {GittalentBackendApplication.class, AbstractSPDataTestConfig.CouchbaseTestConfig.class}) public abstract class AbstractSPDataTestConfig { public static final String clusterUser = "Administrator"; public static final String clusterPassword = "password"; @ClassRule public static CouchbaseContainer couchbaseContainer = new CouchbaseContainer() .withFTS(true) .withIndex(true) .withQuery(true) .withClusterUsername(clusterUser) .withClusterPassword(clusterPassword); @Configuration static class CouchbaseTestConfig implements CouchbaseConfigurer { private CouchbaseContainer couchbaseContainer; @PostConstruct public void init() throws Exception { couchbaseContainer = AbstractSPDataTestConfig.couchbaseContainer; BucketSettings settings = DefaultBucketSettings.builder() .enableFlush(true).name("default").quota(100).replicas(0).type(BucketType.COUCHBASE).build(); settings = couchbaseCluster().clusterManager(clusterUser, clusterPassword).insertBucket(settings); couchbaseContainer.callCouchbaseRestAPI("/settings/indexes", "indexerThreads=0&logLevel=info&maxRollbackPoints=5&storageMode=memory_optimized", "Administrator", "password"); waitForContainer(); } public void waitForContainer(){ CouchbaseWaitStrategy s = new CouchbaseWaitStrategy(); s.withBasicCredentials(clusterUser, clusterPassword); s.waitUntilReady(couchbaseContainer); } @Override @Bean public CouchbaseEnvironment couchbaseEnvironment() { return couchbaseContainer.getCouchbaseEnvironnement(); } @Override @Bean public Cluster couchbaseCluster() throws Exception { return couchbaseContainer.geCouchbaseCluster(); } @Override @Bean public ClusterInfo couchbaseClusterInfo() throws Exception { Cluster cc = couchbaseCluster(); ClusterManager manager = cc.clusterManager(clusterUser, clusterPassword); return manager.info(); } @Override @Bean public Bucket couchbaseClient() throws Exception { return couchbaseContainer.geCouchbaseCluster().openBucket("default"); } } } |
Depois que tivermos esse caso de teste abstrato, tudo o que precisamos fazer é criar uma classe que o estenda e começar a escrever testes! Aqui podemos injetar serviços do nosso aplicativo, bem como um Bucket de nível inferior. O que você vê nesse teste é primeiro uma chamada para um serviço de importação que cria documentos. Em seguida, criamos um índice no bucket padrão e testamos uma consulta nele.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class GitTalentGHImportTests extends AbstractSPDataTestConfig { @Autowired private GithubImportService githubImportService; @Autowired private Bucket bucket; @Test public void importDevAdvocateTeam(){ githubImportService.importOneDeveloper("ldoguin"); N1qlQueryResult result = bucket.query(N1qlQuery.simple("CREATE PRIMARY INDEX ON default")); N1qlQuery query = N1qlQuery.simple("SELECT * FROM default WHERE developerInfo.username = 'ldoguin'"); result = bucket.query(query); N1qlQueryRow row = result.rows().next(); Assert.assertNotNull(row); } } |
Como você pode ver, depois que o caso de teste abstrato é criado, a quantidade de código é realmente mínima e corresponde exatamente ao que você deseja testar.
[Laurent Doguin, defensor dos desenvolvedores do Couchbase, elaborou uma boa visão sobre como testar aplicativos Spring Data Couchbase com Contêineres de Teste e Spring [...]
Olá,
Estou tendo problemas ao criar vários arquivos que estendem a classe Abstract.
Você pode tentar em seu lado? Veja se há algo que estou fazendo errado...
Desde já, obrigado,
Atenciosamente,