LCWD LogoLearn Code With DurgeshLCWD
HomeCoursesTutorialsBlogsContact
About LCWDAbout Durgesh Tiwari
Flex Box Hero
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
  • FlexBox Game

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...

AI: Boon or Curse? Advantages & Disadvantages Explained

AI: Boon or Curse? Advantages & Disadvantages Explained

Artificial Intelligence (AI) is no longer just a concept of the future—it is already shaping our present. From asking Alexa or Siri to play music, using Google Maps for directions, or experiencing personalized recommendations on Netflix, AI has become a part of our everyday life.

The Future of Technology: Quantum Computing and Its Ecosystem

The Future of Technology: Quantum Computing and Its Ecosystem

Quantum computing isn’t just another buzzword—it’s a completely new way of thinking about computers. Unlike our everyday laptops or phones that run on classical computing, quantum computers use the strange but powerful rules of quantum mechanics.

Tailwind CSS Cheat Sheet – Complete Utility Class Guide 2025

Tailwind CSS Cheat Sheet – Complete Utility Class Guide 2025

Tailwind CSS Cheat Sheet – Complete Utility Class Guide 2025

Expert-Level JavaScript Interview Q&A for 2025: Crack Advanced JS Interviews

Expert-Level JavaScript Interview Q&A for 2025: Crack Advanced JS Interviews

Get ready for tough coding interviews with this collection of advanced JavaScript interview questions and answers. Designed for experienced developers who want to master complex JS concepts and impress recruiters.

Ace Your Coding Interview: JavaScript Q&A for Intermediate Learners

Ace Your Coding Interview: JavaScript Q&A for Intermediate Learners

Prepare for your next coding interview with this collection of JavaScript interview questions and answers for intermediate developers. Strengthen your JS concepts and boost your confidence.

Most Asked JavaScript Interview Questions with Answers

Most Asked JavaScript Interview Questions with Answers

Q1. What is JavaScript? JavaScript is a programming language mainly used to make web pages interactive and dynamic. It runs in the browser, and with Node.js, it can also run on the server.

Share this article ...

💬WhatsApp📘Facebook💼LinkedIn🐦X