Complex Object এর জন্য Unit Testing এবং Validation

Jackson এর জন্য Unit Testing - জ্যাকসন (Jackson) - Java Technologies

347

Jackson ব্যবহার করে Complex Object-এর serialization, deserialization, validation এবং Unit Testing অত্যন্ত গুরুত্বপূর্ণ, বিশেষ করে RESTful API ডেভেলপমেন্টে। সঠিক টেস্টিং এবং ভ্যালিডেশন নিশ্চিত করলে ডেটার সঠিকতা এবং অ্যাপ্লিকেশনের নির্ভরযোগ্যতা বজায় থাকে।


Unit Testing এবং Validation এর ধাপসমূহ

  1. Setup for Unit Testing:
    • JUnit বা TestNG টেস্ট ফ্রেমওয়ার্ক ব্যবহার করুন।
    • Jackson-এর ObjectMapper ব্যবহার করে serialization/deserialization টেস্ট করুন।
  2. Data Validation:
    • Java Bean Validation (JSR 380) এর মাধ্যমে ডেটা যাচাই করুন।
    • কাস্টম validation এবং exception handling অন্তর্ভুক্ত করুন।
  3. Testing Complex Objects:
    • Nested objects এবং collections এর জন্য টেস্ট কেস তৈরি করুন।
    • JSON schema validation অন্তর্ভুক্ত করুন।

1. Maven Dependencies

JUnit এবং Jackson-এর জন্য নিম্নলিখিত ডিপেনডেন্সি যুক্ত করুন:

<dependencies>
    <!-- JUnit -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>
    </dependency>

    <!-- Jackson -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
    </dependency>

    <!-- Hibernate Validator -->
    <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>8.0.0.Final</version>
    </dependency>
</dependencies>

2. Complex Object Model তৈরি করুন

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

import java.util.List;

public class Order {
    @NotNull(message = "Order ID cannot be null")
    private String orderId;

    @Valid
    @NotNull(message = "Customer cannot be null")
    private Customer customer;

    @Valid
    @NotNull(message = "Products cannot be null")
    private List<Product> products;

    // Getters and Setters
    public String getOrderId() { return orderId; }
    public void setOrderId(String orderId) { this.orderId = orderId; }

    public Customer getCustomer() { return customer; }
    public void setCustomer(Customer customer) { this.customer = customer; }

    public List<Product> getProducts() { return products; }
    public void setProducts(List<Product> products) { this.products = products; }
}

class Customer {
    @NotNull(message = "Customer Name cannot be null")
    @Size(min = 2, max = 50, message = "Customer Name must be between 2 and 50 characters")
    private String name;

    @NotNull(message = "Email cannot be null")
    private String email;

    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

class Product {
    @NotNull(message = "Product Name cannot be null")
    private String name;

    @NotNull(message = "Price cannot be null")
    private Double price;

    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public Double getPrice() { return price; }
    public void setPrice(Double price) { this.price = price; }
}

3. Unit Test Cases for Serialization and Deserialization

Serialization Test:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;

import java.util.Arrays;

import static org.junit.jupiter.api.Assertions.assertEquals;

class SerializationTest {

    @Test
    void testSerialization() throws Exception {
        ObjectMapper mapper = new ObjectMapper();

        Product product1 = new Product();
        product1.setName("Laptop");
        product1.setPrice(1200.50);

        Product product2 = new Product();
        product2.setName("Mouse");
        product2.setPrice(25.75);

        Customer customer = new Customer();
        customer.setName("Alice");
        customer.setEmail("alice@example.com");

        Order order = new Order();
        order.setOrderId("ORD123");
        order.setCustomer(customer);
        order.setProducts(Arrays.asList(product1, product2));

        String json = mapper.writeValueAsString(order);
        System.out.println("Serialized JSON: " + json);

        // Assert JSON contains key fields
        assertEquals(true, json.contains("ORD123"));
        assertEquals(true, json.contains("Laptop"));
        assertEquals(true, json.contains("Alice"));
    }
}

Deserialization Test:

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertNotNull;

class DeserializationTest {

    @Test
    void testDeserialization() throws Exception {
        ObjectMapper mapper = new ObjectMapper();

        String json = """
                      {
                          "orderId": "ORD123",
                          "customer": {
                              "name": "Alice",
                              "email": "alice@example.com"
                          },
                          "products": [
                              {
                                  "name": "Laptop",
                                  "price": 1200.50
                              },
                              {
                                  "name": "Mouse",
                                  "price": 25.75
                              }
                          ]
                      }
                      """;

        Order order = mapper.readValue(json, Order.class);

        // Assertions
        assertNotNull(order);
        assertNotNull(order.getCustomer());
        assertEquals(2, order.getProducts().size());
    }
}

4. Validation Test Cases

Validation Logic:

import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertFalse;

class ValidationTest {

    private final Validator validator;

    public ValidationTest() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        this.validator = factory.getValidator();
    }

    @Test
    void testValidationErrors() {
        Product product = new Product();
        product.setName("Laptop"); // Missing price

        Customer customer = new Customer();
        customer.setName("Alice");
        customer.setEmail(null); // Invalid email

        Order order = new Order();
        order.setOrderId("ORD123");
        order.setCustomer(customer);
        order.setProducts(Arrays.asList(product));

        Set<jakarta.validation.ConstraintViolation<Order>> violations = validator.validate(order);

        // Assert that validation errors exist
        assertFalse(violations.isEmpty());
        violations.forEach(violation -> System.out.println(violation.getMessage()));
    }
}

আউটপুট:

Price cannot be null
Email cannot be null

5. Exception Handling During Testing

Example of Handling Missing Fields:

@Test
void testMissingFields() {
    ObjectMapper mapper = new ObjectMapper();
    String invalidJson = """
                          {
                              "orderId": "ORD123",
                              "products": []
                          }
                          """;

    Exception exception = null;
    try {
        mapper.readValue(invalidJson, Order.class);
    } catch (Exception e) {
        exception = e;
    }

    assertNotNull(exception);
    System.out.println("Exception: " + exception.getMessage());
}

6. Schema Validation for Complex Objects

JSON Schema Validation:

@Test
void testJsonSchemaValidation() throws Exception {
    String schema = """
                    {
                        "$schema": "http://json-schema.org/draft-07/schema#",
                        "type": "object",
                        "properties": {
                            "orderId": {"type": "string"},
                            "customer": {
                                "type": "object",
                                "properties": {
                                    "name": {"type": "string"},
                                    "email": {"type": "string"}
                                },
                                "required": ["name", "email"]
                            },
                            "products": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "name": {"type": "string"},
                                        "price": {"type": "number"}
                                    },
                                    "required": ["name", "price"]
                                }
                            }
                        },
                        "required": ["orderId", "customer", "products"]
                    }
                    """;

    String jsonData = """
                      {
                          "orderId": "ORD123",
                          "customer": {
                              "name": "Alice",
                              "email": "alice@example.com"
                          },
                          "products": [
                              {"name": "Laptop", "price": 1200.50}
                          ]
                      }
                      """;

    ObjectMapper mapper = new ObjectMapper();
    JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
    JsonSchema jsonSchema = factory.getJsonSchema(mapper.readTree(schema));
    JsonNode data = mapper.readTree(jsonData);

    ProcessingReport report = jsonSchema.validate(data);
    assertTrue(report.isSuccess(), "Validation failed: " + report);
}

  1. Serialization/Deserialization Testing: Complex objects-এর জন্য নিশ্চিত

করুন JSON সঠিকভাবে প্রক্রিয়াজাত হচ্ছে।
2. Validation Testing: Nested objects এবং collections এর জন্য Bean Validation ব্যবহার করুন।
3. Error Handling: Exception Logging এবং Detailed Messages দিয়ে debugging সহজ করুন।
4. Schema Validation: JSON Schema দিয়ে JSON গঠন যাচাই করুন।

এই ধাপগুলো অনুসরণ করে আপনার Complex Object-এর জন্য নির্ভরযোগ্য এবং কার্যকর Unit Testing এবং Validation নিশ্চিত করা সম্ভব।

Content added By
Promotion

Are you sure to start over?

Loading...