afyonkarahisarkitapfuari.com

YugabyteDB Integration Testing with HikariCP and Testcontainers

Written on

Chapter 1: Introduction to YugabyteDB and Testing Frameworks

This guide outlines the process of establishing a basic integration testing setup for YugabyteDB using Spring Boot and Testcontainers. By harnessing the capabilities of Testcontainers, developers can easily configure Docker images tailored for testing. The primary focus here is on utilizing Testcontainers to verify interactions with the Yugabyte database.

What is YugabyteDB?

According to its official website, YugabyteDB is a widely-used distributed SQL database that provides exceptional scalability, fault tolerance, and data durability. It allows users to deploy databases across multiple data centers and cloud providers, ensuring optimal performance and high availability.

What is Spring Boot?

Spring Boot simplifies the creation of stand-alone, production-ready Spring applications that can be executed with minimal setup.

What is Docker?

Docker is an open-source platform that facilitates the development, shipping, and running of applications. It allows developers to separate applications from their infrastructure, enabling faster software delivery.

What is Testcontainers?

Testcontainers is an open-source framework designed to provide lightweight, temporary instances of databases, message brokers, web browsers, or virtually anything else that can run in a Docker container.

Before We Get Started

To follow along, ensure you have the following installed:

  • Docker: Alternatively, you can use a Docker-compatible tool such as Rancher or Podman.
  • Git: This is the preferred method for quickly cloning and running the demo.

How It Started

The project commenced with Spring Boot by visiting start.spring.io/ and including the necessary Maven dependencies: Lombok, Testcontainers, and the PostgreSQL Driver.

Getting the Code

The source code can be cloned from GitHub using the following command:

Code Overview

The ConnectionPool Class

The ConnectionPool.java file is a Java class that implements the DbConnection interface, managing database connections through HikariCPβ€”a lightweight and efficient JDBC connection pooling framework developed by Brett Wooldridge.

To utilize HikariCP, include the following dependency in your pom.xml:

<dependency>

<groupId>com.zaxxer</groupId>

<artifactId>HikariCP</artifactId>

<version>5.1.0</version>

</dependency>

Import the necessary classes from Hikari and the Java SQL package:

import com.zaxxer.hikari.HikariConfig;

import com.zaxxer.hikari.HikariDataSource;

import java.sql.Connection;

A connection can be established as follows:

HikariConfig config = new HikariConfig();

config.setJdbcUrl(url);

config.setUsername(username);

config.setPassword(password);

config.setMaximumPoolSize(10);

create(config);

The CustomerService Class

The Customer.java class represents a Customer object, while CustomerService.java manages customer-related operations. The CustomerService class has a private variable for dbConnection, with its constructor accepting an instance of the DbConnection interface.

public CustomerService(DBConnection dbConnection) {

this.dbConnection = dbConnection;

}

The getCustomer() and createCustomer() methods utilize the Connection object for selecting and inserting data into the Customer table:

public Customer getCustomer(int id) throws SQLException {

try (Connection connection = this.dbConnectionProvider.getConnection()) {

String query = "SELECT * FROM " + TABLE + " WHERE id = ?";

...

}

}

public Customer createCustomer(Customer customer) throws SQLException {

try (Connection connection = this.dbConnectionProvider.getConnection()) {

String query = "INSERT INTO " + TABLE + " (id, name) VALUES (?, ?)";

...

}

}

The Tests

The tests are defined in the CustomerServiceUsingHikariTest class. The class is annotated with several important annotations:

@SpringBootTest

@Testcontainers

@TestMethodOrder(MethodOrderer.MethodName.class)

class CustomerServiceUsingHikariTest {

The @SpringBootTest annotation indicates the use of Spring Boot testing support. The @Testcontainers annotation integrates Testcontainers to manage Docker containers during testing, while the @TestMethodOrder(MethodOrderer.MethodName.class) annotation specifies that tests should run in alphabetical order based on their names.

A static variable for the YugabyteDB container is defined as follows:

static YugabyteDBYSQLContainer yugabyteDBYSQLContainer = new YugabyteDBYSQLContainer("yugabytedb/yugabyte:latest")

.waitingFor(Wait.defaultWaitStrategy());

This variable represents an instance of the YugabyteDB container from Testcontainers, using the official Docker image.

The remaining variables are initialized in the @BeforeAll method, including creating the connectionProvider, TestUtils, and CustomerService objects:

@BeforeAll

static void startDb() throws SQLException, InterruptedException {

yugabyteDBYSQLContainer.start();

final String url = yugabyteDBYSQLContainer.getJdbcUrl().replace("yugabytedb", "postgresql");

dbConnection = new ConnectionPool(url, yugabyteDBYSQLContainer.getUsername(), yugabyteDBYSQLContainer.getPassword());

testUtils = new TestUtils(dbConnection);

testUtils.setUpData();

customerService = new CustomerService(dbConnection);

}

The three methods annotated with @Test are clear in their purpose:

@Test

public void containerRunning() {

// Verify that the container is operational

assertTrue(yugabyteDBYSQLContainer.isRunning());

}

@Test

public void getCustomer() throws SQLException {

// Generate a random customer using test utilities

Customer testCustomer = testUtils.getRandomCustomer();

// Retrieve the customer from the service

Customer customer = customerService.getCustomer(testCustomer.getId());

// Validate the retrieved customer's ID and name

assertEquals(testCustomer.getId(), customer.getId());

assertEquals(testCustomer.getName(), customer.getName());

}

@Test

public void createCustomer() throws SQLException {

// Create a new Customer object

String testName = testUtils.getRandomString(10);

Customer testCustomer = new Customer(testName);

// Create the customer and verify the result

Customer newCustomer = customerService.createCustomer(testCustomer);

assertNotNull(newCustomer);

// Verify the customer was created correctly

Customer customer = customerService.getCustomer(newCustomer.getId());

assertEquals(testName, customer.getName());

}

Running the Tests

To build the project without executing the tests, run the following command in the project directory:

mvn clean spring-boot:run -DskipTests

Expected output:

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 4.265 s

[INFO] Finished at: 2024-03-23T14:35:00Z

[INFO] ------------------------------------------------------------------------

Now, let's execute only the tests:

mvn test -Dtest="CustomerServiceUsingHikariTest"

Expected output:

[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 15.78 s -- in com.example.yugabytedbtestcontainersspringboot.CustomerServiceUsingHikariTest

[INFO]

[INFO] Results:

[INFO]

[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

[INFO]

[INFO] ------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 18.400 s

[INFO] Finished at: 2024-03-23T14:38:50Z

[INFO] ------------------------------------------------------------------------

The tests executed successfully! πŸ˜ƒ πŸ‘

Monitor the logs carefully to trace the execution, which includes checking Docker version compatibility, initiating container creation, waiting for it to be ready, and ultimately connecting using Hikari.

CustomerServiceUsingHikariTest execution logs:

2024-03-23T14:38:48.479Z INFO 7737 --- [yugabytedb-testcontainers-springboot] : Starting CustomerServiceUsingHikariTest using Java 17.0.8

...

Additionally, to build and run the tests in one command, simply execute:

mvn clean package

Summary

In this guide, we explored how to set up integration testing for YugabyteDB using Spring Boot and Testcontainers. By leveraging Testcontainers, developers can effortlessly configure Docker images for testing purposes. This article emphasized the testing of interactions with a Yugabyte database.

With successful test runs and a clear understanding of the integration process, developers can utilize Spring Boot and Testcontainers for efficient and reliable YugabyteDB integration testing in their projects.

Stay tuned for more experiments!

Additional Readings

References

Thank you for reading! Please clap (50 claps) to help spread the word 🌐. Share this article on social media βž• and follow me for more stories on Programming, Career, AI, and more. πŸ””

Discover how to use HikariCP in your next Spring Boot project with this helpful video tutorial.

Learn all about Spring Boot Hikari Connection Pooling in this comprehensive tutorial on YouTube.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Understanding Mood Swings: Are They Beneficial or Detrimental?

Delve into the nature of mood swings, their implications, and how they differ from emotional changes.

Creating a Micro SaaS Empire with No-Code and AI: A Guide

Discover how to leverage No-Code tools and AI to build a successful Micro SaaS business in this comprehensive guide.

# Navigating Loneliness: Lessons from My Grandmother's Wisdom

Reflecting on my grandmother's loneliness has taught me the importance of connection amidst life's distractions.