← Back to Advanced Java Course | Chapter 8: Database & JPA | Lesson 4 of 4

Java की Unit Testing (JUnit)

JUnit आपको छोटे tests लिखने देता है जो जांचते हैं कि आपका code सही जवाब देता है, जैसे कोई teacher अपने आप homework check कर रहा हो। आप नई गलतियां पकड़ने के लिए इन्हें कभी भी चला सकते हैं।
Syntax
java
@Test
void testName() {
    // arrange
    // act
    assertEquals(expected, actual);
}

Assertions

Assertions वह तरीका हैं जिससे कोई test असल में verify करता है कि code ने उम्मीद के मुताबिक result दिया -- assertEquals या assertTrue जैसे methods actual value को expected value से compare करते हैं। अगर comparison fail हो जाए, तो assertion throw करता है, जिसे JUnit पकड़ता है और पूरे run को crash होने देने के बजाय एक failed test के रूप में report करता है।

उदाहरण: Assertions

java
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
public class Main {
	@Test
	void testAddition() {
		int result = 2 + 3;
		assertEquals(5, result); // fails (and is reported) if this doesn't hold
	}
	public static void main(String[] args) {
		new Main().testAddition();
		System.out.println("Assertion passed");
	}
}

The Test Lifecycle

चूंकि unit tests को एक-दूसरे और execution order से स्वतंत्र रूप से चलना चाहिए, JUnit @BeforeEach और @AfterEach जैसे lifecycle annotations प्रदान करता है ताकि किसी test की dependencies को चलने से पहले ताज़ा तैयार किया जा सके और बाद में साफ़ किया जा सके, एक test की state को अगले में लीक होने से रोकते हुए।

उदाहरण: The Test Lifecycle

java
// Import org.junit.jupiter.api.* so it can be used by its short name
import org.junit.jupiter.api.*;
// Define the class Main
public class Main {
	@BeforeEach
	void setup() { System.out.println("Fresh setup before each test"); }
	@AfterEach
	void cleanup() { System.out.println("Cleanup after each test"); }
	@Test
	void sampleTest() { System.out.println("Running test"); }
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		// Create a new Main object and store it in m
		Main m = new Main();
		m.setup(); m.sampleTest(); m.cleanup();
	}
}

Testing Exceptions

आपको explicitly test करना चाहिए कि invalid input मिलने पर आपके methods सही exceptions फेंकते हैं, assertThrows() का उपयोग करते हुए यह दोनों assert करने के लिए कि एक exception फेंका गया और यह सही type का है, सिर्फ happy path test करके कहीं और गलत input के ज़ोर से fail होने की उम्मीद करने के बजाय।

उदाहरण: Testing Exceptions

java
// Import org.junit.jupiter.api.Assertions.* so it can be used by its short name
import static org.junit.jupiter.api.Assertions.*;
// Import org.junit.jupiter.api.Test so it can be used by its short name
import org.junit.jupiter.api.Test;
// Define the class Main
public class Main {
	static void divide(int a, int b) {
		if (b == 0) throw new ArithmeticException("divide by zero");
	}
	@Test
	void testDivideByZero() {
		assertThrows(ArithmeticException.class, () -> divide(10, 0));
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		new Main().testDivideByZero();
		// Print a line to the console
		System.out.println("Exception correctly thrown and verified");
	}
}

Dynamic Parameterized Tests

Parameterized tests (@ParameterizedTest के ज़रिए) आपको अलग-अलग inputs और expected outputs की एक table के खिलाफ एक ही test logic को बार-बार चलाने देते हैं। यह आपकी जांचनी चाही गई हर edge case के लिए लगभग-एक-जैसी test method लिखने से कहीं कम दोहराव वाला है।

उदाहरण: Dynamic Parameterized Tests

java
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
public class Main {
	@ParameterizedTest
	@ValueSource(ints = {2, 4, 6})
	void testEven(int number) {
		System.out.println(number + " is even: " + (number % 2 == 0));
	}
	public static void main(String[] args) {
		Main m = new Main();
		for (int n : new int[]{2, 4, 6}) m.testEven(n); // one method, many inputs
	}
}

Suite Runners

एक पास में पूरे application या module में अपने tests चलाने के लिए, आप individual test classes को एक test suite configuration के अंदर इकट्ठा करते हैं, जिसे फिर JUnit या आपका build tool एक single unit के रूप में execute कर सकता है -- जो CI pipelines के लिए उपयोगी है जिन्हें पूरे codebase के लिए एक pass/fail signal चाहिए।

उदाहरण: Suite Runners

java
import org.junit.platform.suite.api.*;
@Suite
@SelectClasses({}) // aggregates individual test classes for one CI pass/fail signal
public class Main {
	public static void main(String[] args) {
		System.out.println("Suite runs every selected test class as a single unit");
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. assertEquals(result, 5) को गलत order में लिखना, जबकि यह assertEquals(expected, actual) है, जो failure messages को भ्रामक बना देता है।
  2. exceptions को assertThrows के बजाय try/catch से test करना, जिससे कोई exception न फेंके जाने पर भी test pass हो जाता है।
  3. tests को एक-दूसरे पर या shared state के ज़रिए execution order पर निर्भर बनाना, जबकि हर test को अपने आप चलना चाहिए।
चैप्टर सारांश
  • JDBC Java programs को databases से जोड़ता है और create, read, update, और delete operations करता है।
  • Hibernate के साथ ORM Java objects को database tables पर map करता है।
  • JUnit आपके code के लिए unit tests लिखने का एक तरीका प्रदान करता है।
🔒

Chapter Quiz — Complete all 4 topics to unlock

0/4 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.