에서 이전 시리즈 of blog posts I explained how to use TestContainers for your Java Junit tests. Some of the issues we did not address were about how to test N1QL, create your own buckets, index etc… This post will be about building Spring 데이터 카우치베이스 test cases and cover theses questions we left out.
Hardwire Unconfigurable Port
One of the limitations we currently have on Couchbase Server is that you cannot change some of the default port. This is a problem with Docker as it’s changing ports only notified otherwise. This can be great because it means you can have several Couchbase instances running on the same machine. But unfortunately won’t work so some ports will have to be fixed. This can be declared fairly easily with TestContainers using the addFixedExposedPort method.
1 2 3 4 5 6 7 8 9 10 |
@오버라이드 보호됨 void 구성() { 추가 노출된 포트(8091, 11207, 11210, 11211, 18091, 18092, 18093); addFixedExposedPort(8092, 8092); addFixedExposedPort(8093, 8093); addFixedExposedPort(8094, 8094); addFixedExposedPort(8095, 8095); 설정 대기 전략(new HttpWaitStrategy().forPath("/ui/index.html#/")); } |
With that out of the way, our Java SDK will be able to connect to N1QL.
Abstract Spring Data Couchbase Docker Test Case
The goal here is to create an abstract test case that will be used by any class that needs a Couchbase instance and Spring Data Couchbase configured. It starts as in the previous posts by instantiating a CouchbaseContainer field. Since we are testing Spring Data we configure support for Index, Query and let’s throw in FTS for later.
To make sure this class will run tests for your application, add the @RunWith(SpringRunner.class)
annotation. And to make sure your application configuration is tested as well as our custom configuration, add @SpringBootTest(classes = {GittalentBackendApplication.class, AbstractSPDataTestConfig.CouchbaseTestConfig.class})
.
Now talking about custom configuration, what do we need? We want to override the default Couchbase configuration of the app. To do so we need to implement a CouchbaseConfigurer. This interface defines all the bean needed for Spring Data Couchbase to work properly. It provides instances for CouchbaseEnvironment, ClusterInfo, Cluster and Bucket.
They will all come from our CouchbaseContainer setup before running the tests. So we need to make sure that the Container is running and ready before intializing all the beans. This can be achieve by adding an init() method annotated with @PostConstruct. This will allow us to first make sure the container is running, then setup additional stuff. In the following example we setup a bucket called default and setup the Index type to be 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.클래스) @SpringBootTest(클래스 = {GittalentBackendApplication.클래스, AbstractSPDataTestConfig.CouchbaseTestConfig.클래스}) public 초록 클래스 AbstractSPDataTestConfig { public 정적 final 문자열 클러스터 사용자 = "관리자"; public 정적 final 문자열 클러스터 비밀번호 = "비밀번호"; @ClassRule public 정적 카우치베이스 컨테이너 카우치베이스 컨테이너 = new 카우치베이스 컨테이너() .withFTS(true) .withIndex(true) .withQuery(true) .withClusterUsername(클러스터 사용자) .위드클러스터패스워드(클러스터 비밀번호); @구성 정적 클래스 CouchbaseTestConfig 구현 카우치베이스 컨피규레이터 { 비공개 카우치베이스 컨테이너 카우치베이스 컨테이너; @포스트 컨스트럭트 public void init() 던지기 예외 { 카우치베이스 컨테이너 = AbstractSPDataTestConfig.카우치베이스 컨테이너; 버킷 설정 설정 = 기본 버킷 설정.빌더() .활성화Flush(true).이름("default").할당량(100).복제본(0).유형(버킷 유형.터치베이스).빌드(); 설정 = couchbaseCluster().클러스터 관리자(클러스터 사용자, 클러스터 비밀번호).삽입 버킷(설정); 카우치베이스 컨테이너.callCouchbaseRestAPI("/settings/indexes", "indexerThreads=0&logLevel=info&maxRollbackPoints=5&storageMode=memory_optimized", "관리자", "비밀번호"); waitForContainer(); } public void waitForContainer(){ 카우치베이스 대기 전략 s = new 카우치베이스 대기 전략(); s.withBasicCredentials(클러스터 사용자, 클러스터 비밀번호); s.waitUntilReady(카우치베이스 컨테이너); } @오버라이드 @Bean public 카우치베이스 환경 couchbaseEnvironment() { 반환 카우치베이스 컨테이너.getCouchbaseEnvironnement(); } @오버라이드 @Bean public 클러스터 couchbaseCluster() 던지기 예외 { 반환 카우치베이스 컨테이너.geCouchbaseCluster(); } @오버라이드 @Bean public ClusterInfo couchbaseClusterInfo() 던지기 예외 { 클러스터 cc = couchbaseCluster(); ClusterManager 관리자 = cc.클러스터 관리자(클러스터 사용자, 클러스터 비밀번호); 반환 관리자.정보(); } @오버라이드 @Bean public 버킷 카우치베이스클라이언트() 던지기 예외 { 반환 카우치베이스 컨테이너.geCouchbaseCluster().오픈버킷("default"); } } } |
Once we have this abstract test case, all we have to do next is create a class that extends it and start writing tests! Here we can inject Services from our application as well as a lower level Bucket. What you see in this test is first a call to an importer service that create documents. Then we create an Index on the default bucket and test a query on it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public 클래스 GitTalentGHImportTests 확장 AbstractSPDataTestConfig { @자동 유선 비공개 GithubImportService githubImportService; @자동 유선 비공개 버킷 버킷; @테스트 public void importDevAdvocateTeam(){ githubImportService.importOneDeveloper("ldoguin"); N1qlQueryResult 결과 = 버킷.쿼리(N1qlQuery.simple("CREATE PRIMARY INDEX ON default")); N1qlQuery 쿼리 = N1qlQuery.simple("SELECT * FROM default WHERE developerInfo.username = 'ldoguin'"); 결과 = 버킷.쿼리(쿼리); N1qlQueryRow 행 = 결과.행().다음(); Assert.assertNotNull(행); } } |
As you can see once the Abstract test case is created, the amount of code is really minimal and correspond exactly to what you want to test.
[…] Couchbase developer advocate Laurent Doguin put together a nice look at testing Spring Data Couchbase applications with Test Containers and Spring […]
안녕하세요,
I’m having issues when doing multiple files extending the Abstract class.
Can you try on your side ? See if there is something I’m doing wrong…
Thanks in advance,
감사합니다,