Solutions

📘 Introduction

This document contains reference solutions for the exercises and assignments provided in Week 7.

The purpose of these solutions is to:

  • Demonstrate clean coding practices
  • Show proper testing approaches
  • Illustrate validation and logging usage
  • Encourage good backend engineering habits

The learner is encouraged to:

  • Attempt exercises independently first
  • Compare approaches afterward
  • Understand the reasoning behind implementations

Copying solutions directly without understanding is discouraged.


Solution 1 - Basic Unit Testing

Problem

Write unit tests for a Calculator class.


Calculator Class

```java id=”q8q6fd” public class Calculator {

public int add(int a, int b) {
    return a + b;
}

public int subtract(int a, int b) {
    return a - b;
} } ```

Unit Test

```java id=”0xg76z” import org.junit.jupiter.api.Test;

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

class CalculatorTest {

@Test
void shouldAddNumbersCorrectly() {

    Calculator calculator = new Calculator();

    int result = calculator.add(2, 3);

    assertEquals(5, result);
}

@Test
void shouldSubtractNumbersCorrectly() {

    Calculator calculator = new Calculator();

    int result = calculator.subtract(5, 2);

    assertEquals(3, result);
} } ```

Solution 2 - Exception Testing

Problem

Handle division by zero properly.


Updated Calculator

```java id=”rjlwm8” public int divide(int a, int b) {

if (b == 0) {
    throw new IllegalArgumentException(
        "Divisor cannot be zero"
    );
}

return a / b; } ```

Unit Test

```java id=”c7jlwm” @Test void shouldThrowExceptionWhenDivisorIsZero() {

Calculator calculator = new Calculator();

assertThrows(
    IllegalArgumentException.class,
    () -> calculator.divide(10, 0)
); } ```

Solution 3 - Validation Utility

Utility Method

```java id=”nx84mv” public boolean isValidName(String name) {

return name != null
    && !name.isBlank()
    && name.length() >= 3; } ```

Unit Test

```java id=”jlwmv8” @Test void shouldReturnFalseForBlankName() {

ValidationUtil util = new ValidationUtil();

boolean result = util.isValidName(" ");

assertFalse(result); } ```

Solution 4 - DTO Validation

EmployeeRequest DTO

```java id=”r7ux7f” import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank;

public class EmployeeRequest {

@NotBlank(message = "Name cannot be blank")
private String name;

@Email(message = "Invalid email format")
private String email;

@Min(value = 18, message = "Age must be at least 18")
private int age;

// Getters and Setters } ```

Solution 5 - Controller Validation

REST Controller

```java id=”fjlwm0” @RestController @RequestMapping(“/employees”) public class EmployeeController {

@PostMapping
public ResponseEntity<String> createEmployee(
        @Valid @RequestBody EmployeeRequest request) {

    return ResponseEntity.ok("Employee created");
} } ```

Solution 6 - Global Exception Handling

Global Exception Handler

```java id=”ykmjlwm” @RestControllerAdvice public class GlobalExceptionHandler {

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>>
handleValidationException(
        MethodArgumentNotValidException exception) {

    Map<String, String> errors = new HashMap<>();

    exception.getBindingResult()
            .getFieldErrors()
            .forEach(error ->
                errors.put(
                    error.getField(),
                    error.getDefaultMessage()
                )
            );

    return ResponseEntity.badRequest().body(errors);
} } ```

Solution 7 - Logging

Service Layer Logging

```java id=”jlwm73” private static final Logger logger = LoggerFactory.getLogger(EmployeeService.class);


```java id="jlwm11"
public Employee create(EmployeeRequest request) {

    logger.info(
        "Creating employee with email: {}",
        request.getEmail()
    );

    Employee employee = new Employee();

    logger.info(
        "Employee created successfully"
    );

    return employee;
}

Solution 8 - Mockito Example

Service Class

```java id=”jlwm82” @Service public class UserService {

private final UserRepository repository;

public UserService(UserRepository repository) {
    this.repository = repository;
}

public User findById(Long id) {
    return repository.findById(id)
        .orElseThrow(() ->
            new RuntimeException("User not found"));
} } ```

Mockito Test

```java id=”jlwm83” @ExtendWith(MockitoExtension.class) class UserServiceTest {

@Mock
private UserRepository repository;

@InjectMocks
private UserService service;

@Test
void shouldReturnUserSuccessfully() {

    User user = new User();
    user.setId(1L);

    when(repository.findById(1L))
        .thenReturn(Optional.of(user));

    User result = service.findById(1L);

    assertNotNull(result);
} } ```

Solution 9 - Debugging NullPointerException

Problematic Code

```java id=”jlwm84” public void printLength(String value) { System.out.println(value.length()); }


---

## Issue

If `value` is null:

* `NullPointerException` occurs

---

## Improved Solution

```java id="jlwm85"
public void printLength(String value) {

    if (value == null) {
        throw new IllegalArgumentException(
            "Value cannot be null"
        );
    }

    System.out.println(value.length());
}

Solution 10 - Logging Best Practices

Good Logging Example

```java id=”jlwm86” logger.info( “Order created successfully with id: {}”, orderId );


---

# Bad Logging Example

```java id="jlwm87"
System.out.println("Something happened");

Problems:

  • No structure
  • Difficult to filter
  • Not production friendly

Solution 11 - Reading Stack Trace

Example

```text id=”jlwm88” java.lang.NullPointerException at com.example.service.UserService.create(UserService.java:42)


---

## Analysis

This means:

* A null object was accessed
* The issue occurred in:
  `UserService.java`
* At line:
  `42`

---

## Debugging Steps

1. Open file
2. Go to line 42
3. Identify null variable
4. Trace object initialization
5. Add null handling

---

# Solution 12 - Testing Invalid API Payload

## Invalid Request

```json id="jlwm89"
{
  "name": "",
  "email": "invalid-email",
  "age": -1
}

Expected Response

json id="jlwm90" { "name": "Name cannot be blank", "email": "Invalid email format", "age": "Age must be at least 18" }


🧠 Important Engineering Lessons

1. Testing Improves Reliability

Tests help:

  • Prevent regressions
  • Improve confidence
  • Detect issues early

2. Validation Protects Applications

Validation prevents:

  • Corrupted data
  • Invalid requests
  • Unexpected failures

3. Logging Helps Troubleshooting

Good logs:

  • Improve debugging
  • Help production monitoring
  • Explain application behavior

4. Debugging is a Core Skill

Professional developers must:

  • Read stack traces
  • Investigate failures
  • Think logically
  • Isolate root causes

📚 Additional Best Practices

Testing Best Practices

  • Write meaningful test names
  • Keep tests independent
  • Avoid overly complex tests
  • Test edge cases

Logging Best Practices

  • Use appropriate log levels
  • Avoid sensitive information
  • Keep logs meaningful
  • Avoid excessive logging

Validation Best Practices

  • Validate early
  • Return meaningful errors
  • Handle invalid requests gracefully

🏁 Final Outcome

After understanding these solutions, the learner should be able to:

✅ Write basic unit tests ✅ Handle validation properly ✅ Implement exception handling ✅ Add meaningful logs ✅ Debug common runtime issues ✅ Develop production-quality backend habits


💡 Mentor Notes

These solutions represent reference implementations.

Alternative implementations may also be valid if they:

  • Follow clean coding principles
  • Handle edge cases properly
  • Maintain readability and reliability

The focus should always remain on:

  • Learning
  • Understanding
  • Engineering discipline

© 2026 Aditya Pratap Bhuyan Licensed under GPL-3.0 Maintained for backend engineering mentorship and learning.


This site uses Just the Docs, a documentation theme for Jekyll.