1. 개요
Apache Cassandra 는 강력한 오픈 소스 NoSQL 분산 데이터베이스입니다. 이전 사용방법(예제)에서 Cassandra 및 Java 로 작업하는 방법에 대한 몇 가지 기본 사항을 살펴보았습니다 .
이 예제에서는 이전 예제을 기반으로 CassandraUnit 을 사용하여 신뢰할 수 있고 독립적인 단위 테스트를 작성하는 방법을 배웁니다 .
먼저 최신 버전의 CassandraUnit을 설정하고 구성하는 방법부터 살펴보겠습니다. 그런 다음 실행 중인 외부 데이터베이스 서버에 의존하지 않는 단위 테스트를 작성하는 방법에 대한 몇 가지 예를 살펴보겠습니다.
또한 프로덕션에서 Cassandra를 실행하는 경우 자체 서버를 실행하고 유지 관리하는 복잡성을 확실히 제거하고 대신 Apache Cassandra에 구축된 클라우드 기반 데이터베이스 인 Astra 데이터베이스 를 사용할 수 있습니다.
2. 의존성
물론 Apache Cassandra용 표준 Datastax Java 드라이버 를 pom.xml 에 추가해야 합니다 .
<dependency>
<groupId>com.datastax.oss</groupId>
<artifactId>java-driver-core</artifactId>
<version>4.13.0</version>
</dependency>
임베디드 데이터베이스 서버로 코드를 테스트하려면 pom.xml 에도 cassandra-unit 의존성을 추가해야 합니다.
<dependency>
<groupId>org.cassandraunit</groupId>
<artifactId>cassandra-unit</artifactId>
<version>4.3.1.0</version>
<scope>test</scope>
</dependency>
이제 필요한 모든 의존성을 구성했으므로 단위 테스트 작성을 시작할 수 있습니다.
3. 시작하기
이 사용방법(예제) 전체에서 테스트의 초점은 간단한 CQL 스크립트 를 통해 제어하는 간단한 개인 테이블입니다 .
CREATE TABLE person(
id varchar,
name varchar,
PRIMARY KEY(id));
INSERT INTO person(id, name) values('1234','Eugen');
INSERT INTO person(id, name) values('5678','Michael');
앞으로 살펴보겠지만 CassandraUnit은 테스트를 작성하는 데 도움이 되는 몇 가지 변형을 제공하지만 그 중심에는 계속해서 반복할 몇 가지 간단한 개념이 있습니다.
- 먼저 JVM 내에서 메모리 내에서 실행되는 임베디드 Cassandra 서버를 시작합니다.
- 그런 다음 개인 데이터 세트를 실행 중인 임베디드 인스턴스에 로드합니다.
- 마지막으로 간단한 쿼리를 시작하여 데이터가 올바르게 로드되었는지 확인합니다.
이 섹션을 마무리하기 위해 테스트에 대한 간략한 설명입니다. 일반적으로 깨끗한 단위 또는 통합 테스트를 작성할 때 제어할 수 없거나 갑자기 작동이 중지될 수 있는 외부 서비스에 의존해서는 안 됩니다 . 이는 테스트 결과에 악영향을 미칠 수 있습니다.
마찬가지로 외부 서비스에 의존하는 경우(이 경우에는 실행 중인 Cassandra 데이터베이스) 테스트에서 원하는 방식으로 설정, 제어 및 해체할 수 없습니다.
4. 기본 접근 방식을 사용한 테스트
CassandraUnit과 함께 제공되는 기본 API를 사용하는 방법부터 살펴보겠습니다. 먼저 단위 테스트 및 테스트 설정을 정의합니다.
public class NativeEmbeddedCassandraUnitTest {
private CqlSession session;
@Before
public void setUp() throws Exception {
EmbeddedCassandraServerHelper.startEmbeddedCassandra();
session = EmbeddedCassandraServerHelper.getSession();
new CQLDataLoader(session).load(new ClassPathCQLDataSet("people.cql", "people"));
}
}
테스트 설정의 주요 부분을 살펴보겠습니다. 먼저 임베디드 Cassandra 서버를 시작합니다. 이를 위해 startEmbeddedCassandra() 메서드를 호출하기만 하면 됩니다.
그러면 고정 포트 9142를 사용하여 데이터베이스 서버가 시작됩니다.
11:13:36.754 [pool-2-thread-1] INFO o.apache.cassandra.transport.Server
- Starting listening for CQL clients on localhost/127.0.0.1:9142 (unencrypted)...
임의로 사용 가능한 포트를 사용하려는 경우 제공된 Cassandra YAML 구성 파일을 사용할 수 있습니다.
EmbeddedCassandraServerHelper
.startEmbeddedCassandra(EmbeddedCassandraServerHelper.CASSANDRA_RNDPORT_YML_FILE);
마찬가지로 서버를 시작할 때 자체 YAML 구성 파일을 전달할 수도 있습니다. 물론 이 파일은 클래스 경로에 있어야 합니다.
다음으로 계속해서 people.cql 데이터 세트를 데이터베이스에 로드할 수 있습니다. 이를 위해 데이터 세트 위치와 선택적 키스페이스 이름 을 사용하는 ClassPathCQLDataSet 클래스를 사용합니다.
이제 일부 데이터를 로드했고 임베디드 서버가 실행 중이므로 간단한 단위 테스트를 작성할 수 있습니다.
@Test
public void givenEmbeddedCassandraInstance_whenStarted_thenQuerySuccess() throws Exception {
ResultSet result = session.execute("select * from person WHERE id=1234");
assertThat(result.iterator().next().getString("name"), is("Eugen"));
}
보시다시피 간단한 쿼리를 실행하면 테스트가 올바르게 작동하는지 확인할 수 있습니다. 대박! 이제 메모리 내 Cassandra 데이터베이스를 사용하여 자체 포함된 독립 단위 테스트를 작성할 수 있습니다 .
마지막으로 테스트를 해체할 때 포함된 인스턴스를 정리합니다.
@After
public void tearDown() throws Exception {
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
}
이를 실행하면 시스템 키 스페이스를 제외한 모든 기존 키스페이스가 삭제됩니다 .
5. CassandraUnit 추상 JUnit 테스트 사례를 사용한 테스트
이전 섹션에서 본 예제를 단순화하기 위해 CassandraUnit은 추상 테스트 사례 클래스 인 AbstractCassandraUnit4CQLTestCase를 제공합니다. 이 클래스 는 이전에 본 설정 및 해제를 처리합니다.
public class AbstractTestCaseWithEmbeddedCassandraUnitTest
extends AbstractCassandraUnit4CQLTestCase {
@Override
public CQLDataSet getDataSet() {
return new ClassPathCQLDataSet("people.cql", "people");
}
@Test
public void givenEmbeddedCassandraInstance_whenStarted_thenQuerySuccess()
throws Exception {
ResultSet result = this.getSession().execute("select * from person WHERE id=1234");
assertThat(result.iterator().next().getString("name"), is("Eugen"));
}
}
이번에는 AbstractCassandraUnit4CQLTestCase 클래스 를 확장하여 로드하려는 CQLDataSet 을 반환하는 getDataSet() 메서드를 재정의하기만 하면 됩니다.
또 다른 미묘한 차이점은 테스트에서 Cassandra Java 드라이버에 액세스하려면 getSession() 을 호출해야 한다는 것입니다.
6. CassandraCQLUnit JUnit 규칙 을 사용한 테스트
테스트가 AbstractCassandraUnit4CQLTestCase 를 확장하도록 강제하고 싶지 않은 경우 다행히도 CassandraUnit은 표준 JUnit 규칙 도 제공합니다 .
public class JUnitRuleWithEmbeddedCassandraUnitTest {
@Rule
public CassandraCQLUnit cassandra = new CassandraCQLUnit(new ClassPathCQLDataSet("people.cql", "people"));
@Test
public void givenEmbeddedCassandraInstance_whenStarted_thenQuerySuccess() throws Exception {
ResultSet result = cassandra.session.execute("select * from person WHERE id=5678");
assertThat(result.iterator().next().getString("name"), is("Michael"));
}
}
우리가 해야 할 일은 테스트에서 표준 JUnit @Rule 인 CassandraCQLUnit 필드를 선언하는 것 입니다. 이 규칙은 Cassandra Server의 수명 주기를 준비하고 관리합니다.
7. 스프링 작업
일반적으로 프로젝트에서 Cassandra를 Spring과 통합할 수 있습니다. 다행스럽게도 CassandraUnit은 Spring TestContext Framework 작업을 지원합니다.
이 지원을 활용하려면 프로젝트에 cassandra-unit-spring Maven 의존성을 추가해야 합니다.
<dependency>
<groupId>org.cassandraunit</groupId>
<artifactId>cassandra-unit-spring</artifactId>
<version>4.3.1.0</version>
<scope>test</scope>
</dependency>
이제 테스트에서 사용할 수 있는 여러 어노테이션 및 클래스에 액세스할 수 있습니다. 가장 기본적인 Spring 구성을 사용하는 테스트를 작성해 보겠습니다.
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({ CassandraUnitTestExecutionListener.class })
@CassandraDataSet(value = "people.cql", keyspace = "people")
@EmbeddedCassandra
public class SpringWithEmbeddedCassandraUnitTest {
@Test
public void givenEmbeddedCassandraInstance_whenStarted_thenQuerySuccess() throws Exception {
CqlSession session = EmbeddedCassandraServerHelper.getSession();
ResultSet result = session.execute("select * from person WHERE id=1234");
assertThat(result.iterator().next().getString("name"), is("Eugen"));
}
}
테스트의 핵심 부분을 살펴보겠습니다. 먼저 테스트 클래스를 두 가지 표준 Spring 관련 어노테이션으로 장식하는 것으로 시작합니다.
- @RunWith(SpringJUnit4ClassRunner.class) 어노테이션은 테스트가 Spring의 TestContextManager 를 테스트에 포함하도록 하여 Spring ApplicationContext에 대한 액세스를 제공합니다.
- 또한 CassandraUnitTestExecutionListener 라는 사용자 지정 TestExecutionListener 를 지정합니다. CassandraUnitTestExecutionListener 는 서버 시작 및 중지와 다른 CassandraUnit 어노테이션 찾기를 담당합니다.
여기에 중요한 부분이 있습니다. @EmbeddedCassandra 어노테이션을 사용 하여 임베디드 Cassandra 서버의 인스턴스를 테스트에 주입합니다 . 또한 임베디드 데이터베이스 서버를 추가로 구성하는 데 사용할 수 있는 몇 가지 속성이 있습니다.
- 구성 – 다른 Cassandra 구성 파일
- clusterName – 클러스터의 이름
- 호스트 – 클러스터의 호스트
- 포트 – 클러스터에서 사용하는 포트
여기서는 선언에서 이러한 속성을 생략하여 기본값을 선택하여 간단하게 유지했습니다.
퍼즐의 마지막 조각을 위해 @CassandraDataSet 어노테이션을 사용하여 이전에 본 것과 동일한 CQL 데이터 세트를 로드합니다. 이전과 같은 방식으로 데이터베이스의 내용이 올바른지 확인하기 위해 쿼리를 보낼 수 있습니다.
8. 결론
이 기사에서는 Apache Cassandra의 임베디드 인스턴스를 사용하여 독립 실행형 단위 테스트를 작성하기 위해 CassandraUnit과 함께 작업할 수 있는 몇 가지 방법을 배웠습니다. 또한 단위 테스트에서 Spring과 작업하는 방법에 대해서도 논의했습니다.
언제나처럼 기사의 전체 소스 코드는 GitHub에서 확인할 수 있습니다 .