স্প্রিং জেডিবিসি (Spring JDBC) অ্যাপ্লিকেশনটি পরীক্ষা (Testing) করা গুরুত্বপূর্ণ, কারণ এটি নিশ্চিত করে যে আপনার ডেটাবেস ইন্টারঅ্যাকশন সঠিকভাবে কাজ করছে। স্প্রিং জেডিবিসি টেস্টিংয়ে সাধারণত JUnit এবং Mockito ব্যবহৃত হয়, যেখানে JdbcTemplate এর কার্যকারিতা পরীক্ষার জন্য ফেইক বা মক (mock) ডেটাবেস ব্যবহার করা হয়।
স্প্রিং জেডিবিসি টেস্টিং করার জন্য আমরা সাধারণত দুটি পদ্ধতি ব্যবহার করি:
- Integration Testing (প্রকৃত ডেটাবেসের সাথে)
- Unit Testing (Mockito বা H2 ডেটাবেস ব্যবহার করে)
1. Spring JDBC Integration Testing (প্রকৃত ডেটাবেসের সাথে)
Integration Testing এর মধ্যে আমরা প্রকৃত ডেটাবেস (যেমন H2 ইন-মেমরি ডেটাবেস) ব্যবহার করি, যাতে আমরা নিশ্চিত হতে পারি যে আমাদের কোড ডেটাবেসের সাথে সঠিকভাবে কাজ করছে।
1.1. H2 ইন-মেমরি ডেটাবেস ব্যবহার
H2 একটি ইন-মেমরি ডেটাবেস যা স্প্রিং জেডিবিসি পরীক্ষার জন্য বেশ উপযুক্ত। এটি কোনো নির্দিষ্ট কনফিগারেশন ছাড়াই ডেটাবেস তৈরি করতে সহায়ক।
pom.xml এ H2 ডিপেনডেন্সি যুক্ত করুন:
<dependencies>
<!-- Spring JDBC Dependency -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.20</version>
</dependency>
<!-- H2 Database for testing -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
<scope>test</scope>
</dependency>
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<!-- Spring Test Dependency -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.20</version>
<scope>test</scope>
</dependency>
</dependencies>
1.2. Spring JDBC Testing Example
ধরা যাক আমাদের একটি EmployeeDao ক্লাস রয়েছে যা JdbcTemplate ব্যবহার করে ডেটাবেস থেকে ডেটা রিট্রিভ বা ইনসার্ট করে। এখন এই ক্লাসটির টেস্ট করতে হবে।
EmployeeDao.java:
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class EmployeeDao {
private JdbcTemplate jdbcTemplate;
public EmployeeDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void addEmployee(int id, String name, double salary) {
String sql = "INSERT INTO Employee (id, name, salary) VALUES (?, ?, ?)";
jdbcTemplate.update(sql, id, name, salary);
}
public Employee getEmployee(int id) {
String sql = "SELECT * FROM Employee WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(Employee.class));
}
}
Integration Test with H2:
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
public class EmployeeDaoTest {
@Autowired
private EmployeeDao employeeDao;
@Autowired
private JdbcTemplate jdbcTemplate;
@BeforeEach
public void setup() {
// Set up in-memory H2 database for testing
jdbcTemplate.execute("CREATE TABLE Employee (id INT, name VARCHAR(255), salary DOUBLE)");
}
@Test
public void testAddEmployee() {
// Test the insert functionality
employeeDao.addEmployee(1, "John Doe", 50000);
Employee employee = employeeDao.getEmployee(1);
assertNotNull(employee);
assertEquals("John Doe", employee.getName());
assertEquals(50000, employee.getSalary());
}
@Test
public void testGetEmployee() {
// Add employee for testing
jdbcTemplate.update("INSERT INTO Employee (id, name, salary) VALUES (2, 'Jane Smith', 60000)");
Employee employee = employeeDao.getEmployee(2);
assertNotNull(employee);
assertEquals("Jane Smith", employee.getName());
assertEquals(60000, employee.getSalary());
}
}
ব্যাখ্যা:
@SpringBootTest: এটি স্প্রিং অ্যাপ্লিকেশন কনটেক্সট লোড করতে ব্যবহৃত হয়, যাতেEmployeeDaoক্লাস এবংJdbcTemplateক্লাস টেস্ট করা যায়।@Autowired: স্প্রিং দ্বারাEmployeeDaoএবংJdbcTemplateইনজেক্ট করা হয়।- H2 ডেটাবেস: টেস্ট শুরু করার আগে
CREATE TABLESQL স্টেটমেন্টের মাধ্যমে টেস্ট ডেটাবেস তৈরি করা হয়। - JUnit assertions:
assertNotNullএবংassertEqualsমেথড ব্যবহার করা হয়েছে নিশ্চিত করতে যে ইনসার্ট এবং রিটার্ন অপারেশন সঠিকভাবে কাজ করছে।
2. Spring JDBC Unit Testing with Mockito
Mockito ব্যবহার করে Unit Testing করতে গেলে, আমরা ডেটাবেস ইন্টারঅ্যাকশন মক করতে পারি, যাতে প্রকৃত ডেটাবেস কনফিগারেশন ছাড়া শুধুমাত্র লজিক টেস্ট করা যায়। এখানে আমরা Mockito এবং JdbcTemplate মক করতে দেখাবো।
2.1. Mockito Setup:
pom.xml এ Mockito ডিপেনডেন্সি যুক্ত করুন:
<dependencies>
<!-- Mockito for Unit Testing -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.5.0</version>
<scope>test</scope>
</dependency>
</dependencies>
2.2. Unit Test with Mockito:
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
@ExtendWith(MockitoExtension.class)
public class EmployeeDaoUnitTest {
@Mock
private JdbcTemplate jdbcTemplate;
@InjectMocks
private EmployeeDao employeeDao;
@Test
public void testGetEmployee() {
// Arrange
Employee mockEmployee = new Employee(1, "John Doe", 50000);
when(jdbcTemplate.queryForObject(anyString(), any(Object[].class), any(BeanPropertyRowMapper.class)))
.thenReturn(mockEmployee);
// Act
Employee employee = employeeDao.getEmployee(1);
// Assert
assertNotNull(employee);
assertEquals("John Doe", employee.getName());
assertEquals(50000, employee.getSalary());
}
@Test
public void testAddEmployee() {
// Arrange
doNothing().when(jdbcTemplate).update(anyString(), any(), any(), any());
// Act
employeeDao.addEmployee(2, "Jane Smith", 60000);
// Assert
verify(jdbcTemplate, times(1)).update(anyString(), any(), any(), any());
}
}
ব্যাখ্যা:
- Mockito Mocks:
@Mockদিয়েJdbcTemplateকে মক করা হয়েছে যাতে প্রকৃত ডেটাবেস অ্যাক্সেস না হয়। when()এবংthenReturn(): মক স্টেটমেন্টের জন্য ব্যবহার করা হয়েছে, যাতেjdbcTemplate.queryForObject()মেথড একটি নির্দিষ্ট মান রিটার্ন করে।verify(): পরীক্ষা করা হয়েছে যেupdate()মেথড একবার কল করা হয়েছে কিনা।
উপসংহার:
- Integration Testing তে প্রকৃত ডেটাবেস ব্যবহার করা হয় যাতে ডেটাবেস ইন্টারঅ্যাকশন সঠিকভাবে কাজ করছে কিনা তা পরীক্ষা করা যায়।
- Unit Testing তে Mockito ব্যবহার করে শুধুমাত্র ডেটাবেস ইন্টারঅ্যাকশন নয়,
JdbcTemplateএর মতো ক্লাসও মক করা যায়। - দুই পদ্ধতিতেই টেস্টিং গুরুত্বপূর্ণ, কারণ এটি আপনার কোডের মান এবং কর্মক্ষমতা নিশ্চিত করতে সাহায্য করে।
Read more