Tuesday, March 25, 2014

Cassandra unit test with Spring framework

To unit test a method that manipulates the Cassandra database, you can use cassandra-unit-spring to make life a lot easier. With this dependency, there is no need to launch the Cassandra database every time to run the test cases. Instead, it will start embedded Cassandra when the test is running.

First, add the cassandra-unit-spring dependency in your maven pom.xml, currently the latest version is 2.0.2.0
<dependency>
    <groupid>org.cassandraunit</groupid>
    <artifactid>cassandra-unit-spring</artifactid>
    <version>2.0.2.0</version>
</dependency>

Then write your configuration class, here you can import other configurations from .xml file using @ImportResource annotation
@Configuration
@ImportResource({"classpath:META-INF/spring/applicationContext*.xml"})
public class CassandraTestConfig {
 @Bean(destroyMethod = "close")
 public Cluster cluster() throws ConfigurationException, TTransportException, IOException, InterruptedException{

  EmbeddedCassandraServerHelper.startEmbeddedCassandra();
  Cluster cluster = Cluster.builder().addContactPoints("127.0.0.1").withPort(9142).build();

  return cluster;
 }
}

And your test class, in order to enable Autowired annotation in spring framework, "DependencyInjectionTestExecutionListener.class" should be included in TestExecutionListeners.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {CassandraTestConfig.class})
@TestExecutionListeners({CassandraUnitTestExecutionListener.class, DependencyInjectionTestExecutionListener.class})
@EmbeddedCassandra
public class CqlTitleNewsRepositoryTest {
 
 @Autowired
 private MyDataRepository myDataRepository;
 
 @Test
 public void testMyRepo() throws IOException {
  
  MyData myData = new MyData();
  myDataRepository.save(myData);
  // your assertions
}
Notes: 
1. If there are multiple test cases, after each test, all non-system keyspace will be dropped. You can either create the keyspace you need before each test, or use @CassandraDataSet annotation to include a dataset definition file to initialize the keyspace.
2. If you have prepared statements in your target code, you need to include "cassandra-all" dependency with version equal or above 2.0.3. Because the cassandra-all version included in cassandra-unit-spring 2.0.2.0 is 2.0.2, it can cause exception "IllegalStateException: Instrumentation is not set; Jamm must be set as -javaagent" as described here: CASSANDRA-6107 causes EmbeddedCassandraService to fail

No comments:

Post a Comment