JUnit 5


Spring Boot অ্যাপ্লিকেশন তৈরি করার সময় Unit Testing সবচেয়ে গুরুত্বপূর্ণ বিষয়গুলোর একটি Java ecosystem-এ সবচেয়ে জনপ্রিয় টেস্টিং ফ্রেমওয়ার্ক হলো JUnit। এবং Spring Boot এখন JUnit 5 (Jupiter) এর সাথে সম্পূর্ণভাবে ইন্টিগ্রেটেড।


কেন JUnit 5?

JUnit 5, JUnit 4 এর তুলনায় অনেক বেশি আধুনিক, modular এবং flexible। এতে তিনটি মূল অংশ রয়েছে:

Module কাজ
JUnit Platform Test engine চালানোর বেস ফ্রেমওয়ার্ক
JUnit Jupiter নতুন annotations এবং API
JUnit Vintage পুরনো JUnit 3/4 টেস্ট চালানোর জন্য


Dependency সেটআপ

pom.xml ফাইলে নিচের dependency যোগ করলেই JUnit 5 চলে যাবে (Spring Boot Starter Test এর মাধ্যমেই):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

Spring Boot 2.2+ থেকে JUnit 5 ডিফল্টভাবে থাকে, তাই আলাদা কিছু করার প্রয়োজন নেই।


একটি সাধারণ Unit Test উদাহরণ

ধরা যাক আমাদের একটি সার্ভিস ক্লাস আছে:

@Service
public class CalculatorService {
    public int add(int a, int b) {
        return a + b;
    }

    public int divide(int a, int b) {
        return a / b;
    }
}


এখন আমরা এর জন্য টেস্ট লিখব:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class CalculatorServiceTest {

    private final CalculatorService service = new CalculatorService();

    @Test
    void testAddition() {
        assertEquals(5, service.add(2, 3));
    }

    @Test
    void testDivision() {
        assertThrows(ArithmeticException.class, () -> service.divide(5, 0));
    }
}


JUnit 5 Annotations

Annotation কাজ
@Test টেস্ট মেথড নির্দেশ করে
@BeforeEach প্রতিটি টেস্টের আগে রান হয়
@AfterEach প্রতিটি টেস্টের পর রান হয়
@BeforeAll সব টেস্টের আগে একবার রান হয় (static হতে হবে)
@AfterAll সব টেস্টের পরে একবার রান হয় (static হতে হবে)
@DisplayName টেস্টের জন্য কাস্টম নাম সেট করে
@Disabled কোনো টেস্ট skip করতে ব্যবহার হয়


উদাহরণ:

@BeforeAll
static void setup() {
    System.out.println("Starting tests...");
}

@BeforeEach
void init() {
    System.out.println("Init before each test");
}

@AfterEach
void tearDown() {
    System.out.println("Cleaning up...");
}


Assertions API

JUnit 5 এ org.junit.jupiter.api.Assertions প্যাকেজে বেশ কিছু শক্তিশালী assertion method আছে:

Assertion কাজ
assertEquals(expected, actual) দুটি মান সমান কিনা যাচাই করে
assertNotNull(object) অবজেক্ট null নয় কিনা যাচাই করে
assertTrue(condition) শর্ত সত্য কিনা যাচাই করে
assertThrows(Exception.class, ...) Exception ছোঁড়া হয়েছে কিনা চেক করে
assertAll(...) একাধিক assertion একসাথে রান করে


উদাহরণ:

@Test
void testMultipleAssertions() {
    assertAll(
        () -> assertEquals(10, 5 + 5),
        () -> assertTrue("Hello".startsWith("H")),
        () -> assertNotNull(new Object())
    );
}


Parameterized Tests

JUnit 5 এর সবচেয়ে আকর্ষণীয় ফিচার হলো @ParameterizedTest, যার মাধ্যমে আমরা একই টেস্টে একাধিক ইনপুট দিয়ে ফলাফল যাচাই করতে পারি।

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class ParameterizedExampleTest {

    @ParameterizedTest
    @ValueSource(strings = {"Spring", "JUnit", "Mockito"})
    void testStringNotEmpty(String word) {
        assertFalse(word.isEmpty());
    }
}

এছাড়াও আমরা @CsvSource, @EnumSource, @MethodSource ইত্যাদি ব্যবহার করতে পারি।


Spring Boot Integration সহ JUnit 5

Spring Boot অ্যাপ্লিকেশন context লোড করে টেস্ট চালাতে চাইলে ব্যবহার করো @SpringBootTest:

@SpringBootTest
class ApplicationIntegrationTest {

    @Autowired
    private CalculatorService service;

    @Test
    void testServiceBean() {
        assertNotNull(service);
        assertEquals(7, service.add(3, 4));
    }
}

👉 এখানে Spring Boot পুরো context লোড করে এবং bean injection সম্পন্ন করে।


Mocking সহ JUnit + Mockito

Spring Boot টেস্টে mock object ব্যবহার করতে চাইলে @Mock@InjectMocks ব্যবহার করো:

@ExtendWith(MockitoExtension.class)
class UserServiceTest {

    @Mock
    private UserRepository repo;

    @InjectMocks
    private UserService service;

    @Test
    void testGetUser() {
        when(repo.findById(1L)).thenReturn(Optional.of(new User(1L, "Maruf")));

        User user = service.getUserById(1L);
        assertEquals("Maruf", user.getName());
    }
}


@DataJpaTest — Repository Testing

Spring Data JPA repository টেস্ট করার জন্য সবচেয়ে জনপ্রিয় annotation হলো @DataJpaTest:

@DataJpaTest
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    void testSaveUser() {
        User user = new User(null, "Rihan");
        User saved = userRepository.save(user);
        assertNotNull(saved.getId());
    }
}

এটি ইন-মেমোরি ডাটাবেজ (যেমন H2) ব্যবহার করে এবং শুধুমাত্র repository সম্পর্কিত bean লোড করে।


Nested Tests

JUnit 5 এ nested test class ব্যবহার করা যায়, যা টেস্ট সংগঠিত রাখতে সহায়তা করে।

class MathTest {

    @Nested
    class AddTests {
        @Test
        void addTwoNumbers() {
            assertEquals(8, 3 + 5);
        }
    }

    @Nested
    class SubtractTests {
        @Test
        void subtractNumbers() {
            assertEquals(2, 5 - 3);
        }
    }
}


Tips & Best Practices

- টেস্ট ক্লাসের নাম শেষে “Test” রাখো (যেমন UserServiceTest)
- প্রতিটি ইউনিট আলাদা টেস্টে ভাঙো
- টেস্ট নাম অর্থবোধক রাখো (shouldReturnUserWhenIdIsValid())
- Mock ব্যবহার করো external dependency এর জন্য
- CI/CD তে mvn test বা gradle test চালাও