LCWD LogoLearn Code With DurgeshLCWD
HomeCoursesBlogsContact
LearnCodeWithDurgesh Logo

Learn Code With Durgesh

Offering free & premium coding courses to lakhs of students via YouTube and our platform.

Explore

  • About Us
  • Courses
  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms & Conditions
  • Refund Policy
  • Support

Contact

  • 📞 +91-9839466732
  • [email protected]
  • Substring Technologies, 633/D/P256 B R Dubey Enclave Dhanwa Deva Road Matiyari Chinhat, Lucknow, UP, INDIA 226028
© 2025 Made with ❤️ by Substring Technologies. All rights reserved.
JUnit 5 and Mockito – From Scratch to Advanced

JUnit 5 and Mockito – From Scratch to Advanced

By durgeshkumar8896 • Wed Aug 13 2025

JUnit 5 and Mockito – From Scratch to Advanced

JUnit 5 and Mockito Guide – From Scratch to Advanced (with Real-Time Spring Boot Examples)

Introduction

Imagine building a skyscraper without checking the strength of each floor. Risky, right?
That’s exactly what happens in software when we skip testing — we risk everything collapsing later.

In this guide, we’ll master JUnit 5 and Mockito from the ground up, moving from basic unit tests to advanced real-world scenarios like mocking APIs, testing exceptions, and measuring coverage with JaCoCo — all in a Spring Boot application.

By the end, you’ll have:

  • A complete testing toolkit for controllers, services, and repositories.

  • Confidence to write tests for real production scenarios.

  • Knowledge of best practices and common pitfalls to avoid.

 

1. Unit Testing vs Integration Testing – How JUnit Fits In

Unit Testing:

  • Tests individual components (e.g., a method in a service class).

  • Fast, isolated, no database or network calls.

  • Example: Testing a calculateFare() method without hitting the DB.

Integration Testing:

  • Tests multiple layers together (controller → service → repository).

  • May involve DB, APIs, message queues.

  • Example: Testing a booking API end-to-end with a real DB.

Where JUnit Fits In:

  • JUnit is a testing framework that lets you write and run repeatable tests in Java.

  • Works for both unit and integration tests.

  • Plays well with Mockito for mocking.

Mini Exercise:

  • Write down 3 examples from your project that should be tested as unit tests and 3 as integration tests.

2. JUnit 5 Features & Annotations with Examples

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage.

Common Annotations:

AnnotationPurpose
@TestMarks a test method
@BeforeEachRuns before each test
@AfterEachRuns after each test
@BeforeAllRuns once before all tests
@AfterAllRuns once after all tests
@DisplayNameCustom name for test
@DisabledSkips a test
@ParameterizedTestRuns the same test with different inputs
class CalculatorTest {

    Calculator calc;

    @BeforeEach
    void init() {
        calc = new Calculator();
    }

    @Test
    @DisplayName("Addition Test")
    void testAdd() {
        assertEquals(5, calc.add(2, 3));
    }
}

3. Setting Up JUnit 5 in Spring Boot

Maven Dependency:

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

This brings:

  • JUnit 5

  • Mockito

  • Spring Test

  • AssertJ, Hamcrest

Test Folder Structure:

src
 ├── main
 │    ├── java/com/example/demo
 │    └── resources
 └── test
      ├── java/com/example/demo
      └── resources

4. Real-World Example Project – Train Booking App

We’ll test a Train Booking service with:

  • Controller

  • Service

  • Repository

  • External API for train availability

Entitry

@Entity
public class Booking {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String trainName;
    private String passengerName;
    private double fare;

    // Constructors, getters, setters
}

Repository

public interface BookingRepository extends JpaRepository<Booking, Long> {
}

Service

@Service
public class BookingService {

    @Autowired
    private BookingRepository bookingRepository;

    public Booking createBooking(Booking booking) {
        booking.setFare(calculateFare(booking.getTrainName()));
        return bookingRepository.save(booking);
    }

    public Booking getBooking(Long id) {
        return bookingRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Booking not found"));
    }

    public double calculateFare(String trainName) {
        return trainName.contains("AC") ? 1500.0 : 800.0;
    }
}

Controller

@RestController
@RequestMapping("/bookings")
public class BookingController {

    @Autowired
    private BookingService bookingService;

    @PostMapping
    public ResponseEntity<Booking> createBooking(@RequestBody Booking booking) {
        return ResponseEntity.ok(bookingService.createBooking(booking));
    }

    @GetMapping("/{id}")
    public ResponseEntity<Booking> getBooking(@PathVariable Long id) {
        return ResponseEntity.ok(bookingService.getBooking(id));
    }
}

 

5. Writing Tests with Mockito

Service Layer Test

@ExtendWith(MockitoExtension.class)
class BookingServiceTest {

    @Mock
    BookingRepository bookingRepository;

    @InjectMocks
    BookingService bookingService;

    @Test
    void testCreateBooking() {
        Booking booking = new Booking();
        booking.setTrainName("AC Express");

        when(bookingRepository.save(any(Booking.class)))
            .thenReturn(new Booking(1L, "AC Express", "John", 1500.0));

        Booking savedBooking = bookingService.createBooking(booking);

        assertEquals(1500.0, savedBooking.getFare());
        verify(bookingRepository, times(1)).save(any(Booking.class));
    }
}

6. Testing Repository with H2

@DataJpaTest
class BookingRepositoryTest {

    @Autowired
    BookingRepository bookingRepository;

    @Test
    void testSaveAndFind() {
        Booking booking = new Booking();
        booking.setTrainName("Sleeper Express");
        booking.setPassengerName("Alice");
        booking.setFare(800.0);

        bookingRepository.save(booking);

        List<Booking> bookings = bookingRepository.findAll();
        assertEquals(1, bookings.size());
    }
}

7. Testing Controller with MockMvc

@WebMvcTest(BookingController.class)
class BookingControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private BookingService bookingService;

    @Test
    void testGetBooking() throws Exception {
        Booking booking = new Booking(1L, "AC Express", "John", 1500.0);
        when(bookingService.getBooking(1L)).thenReturn(booking);

        mockMvc.perform(get("/bookings/1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.trainName").value("AC Express"));
    }
}

8. Advanced Scenarios

  • Mocking External APIs → WireMock setup

  • Testing Exceptions → assertThrows(RuntimeException.class, ...)

  • Parameterized Tests → @CsvSource({"AC Express,1500.0", "Sleeper Express,800.0"})

  • Verifying Calls → verify(bookingRepository, times(1)).save(any())

 

9. Best Practices

  • Test method naming: methodName_expectedBehavior_condition

  • Keep tests independent

  • Avoid over-mocking

  • Target 80%+ coverage but don’t write useless tests

 

10. JaCoCo Setup

Maven Plugin:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.8</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Run:

mvn clean test

Report will be in:

target/site/jacoco/index.html

Conclusion

Testing isn’t just about finding bugs — it’s about building confidence in your code.
With JUnit 5 and Mockito, you can write clean, fast, reliable tests for any Spring Boot app.

Share this article ...

💬WhatsApp📘Facebook💼LinkedIn🐦X

Trending Blogs...

HTML the Easy Way-Unlock the web

HTML the Easy Way-Unlock the web

If you’ve ever wondered how websites are built, here’s the secret: almost every webpage you see starts with HTML. Whether it’s a simple blog post, an online shop, or a social media site – HTML is the foundation.

JUnit 5 and Mockito – From Scratch to Advanced

JUnit 5 and Mockito – From Scratch to Advanced

Learn JUnit 5 & Mockito from scratch to advanced with real-time Spring Boot examples. Covers unit & integration testing, annotations, MockMvc, H2 DB, and best practices.

Modern JavaScript for Developers in 2026

Modern JavaScript for Developers in 2026

Discover the modern JavaScript features developers should know in 2026 and learn how to future-proof your skills for the evolving web landscape. This in-depth guide covers JavaScript trends 2026, emerging frameworks, and best practices to help you stay ahead in web development. Explore the top JavaScript frameworks to watch in 2026, find out what’s new in modern JS features, and see how AI-assisted JavaScript development is shaping the future. Whether you’re updating your JavaScript developer roadmap 2026 or just getting started, this article will help you master the modern JavaScript tools and techniques needed to build fast, scalable, and future-ready applications.

Debouncing in JavaScript

Debouncing in JavaScript

In this article we will learn about the debouncing . We will learn about actual real problem and how to solve this problem using js debouncing.

Maven Tutorial

Maven Tutorial

Maven is a build automation tool primarily used for Java projects. It addresses two main aspects of building software: dependency management and project build lifecycle management.

Share this article ...

💬WhatsApp📘Facebook💼LinkedIn🐦X