Oops! Sorry!!


This site doesn't support Internet Explorer. Please use a modern browser like Chrome, Firefox or Edge.

🧪 Mastering JUnit & Mockito in Java: The Ultimate Beginner’s Guide to Unit Testing (Free Cheat Sheet Inside)

Are you preparing for a Java coding interview or looking to write clean, testable Java code? Then you must understand how to use JUnit and Mockito, the two most powerful testing tools in the Java ecosystem.

This article is your complete guide to mastering JUnit and Mockito, even if you’re just starting out. I’ve organized every important component and annotation with simple explanations and practical use. Plus — I’m giving you a free downloadable cheat sheet at the end to accelerate your learning.

Let’s dive in.

✅ Why Learn JUnit & Mockito?

Java is one of the most in-demand programming languages in the world. Whether you’re applying for a backend developer, cloud engineer, or full-stack role, employers expect you to know how to:

That’s exactly where JUnit and Mockito come in.

  • Write testable code
  • Catch bugs early
  • Build reliable enterprise applications

🤔 What is Unit Testing?

Imagine building a car. Would you test all parts together at once — or test the engine, brakes, and tires one by one to make sure each works correctly?

That’s exactly what unit testing is.

🔍 Unit testing is testing a small piece of code (like a method or class) in isolation, to make sure it works as expected.

For Java developers, the most popular tools used for unit testing are:

✅ JUnit – for writing the tests

✅ Mockito – for faking/mocking dependencies

🧪 What is JUnit?

JUnit is a free and open-source testing framework for Java. It helps you write test methods that automatically check if your code is working correctly.

You’ll use JUnit to:

Run tests quickly Catch bugs early Automate checking your code

🔁 What is Mockito?

Mockito is a Java tool that helps you fake (mock) other parts of the code that your class depends on. This way, you can test just your logic without relying on a real database or API.

For example: If UserService depends on UserRepository, you can use Mockito to mock UserRepository and test only UserService.

📚 Step-by-Step: JUnit Annotations (Explained Simply)

AnnotationWhat It Does (Simple Explanation)@TestMarks a method as a test. JUnit runs this method.@BeforeEachRuns before every test. Used to set up common test data.@AfterEachRuns after every test. Good for cleanup.@BeforeAllRuns once before all tests. Must be static.@AfterAllRuns once after all tests. Also must be static.@DisplayNameAdds a custom name to the test (for better readability).@DisabledTemporarily turns off a test method.

🧪 Step-by-Step: Mockito Annotations (Made Easy)

AnnotationWhat It Does@MockCreates a fake object of a class/interface.@InjectMocksAutomatically injects the mocks into the class you want to test.@SpyWraps a real object but allows you to mock specific methods.@CaptorCaptures the arguments passed to mock methods.@ExtendWith(MockitoExtension.class)Allows Mockito to work with JUnit 5.

🛠️ Common JUnit Assertion Methods (To Check Your Results)

MethodWhat It ChecksassertEquals(a, b)If two values are equal.assertTrue(condition)If the condition is true.assertFalse(condition)If the condition is false.assertThrows(Exception.class, () -> ...)If a method throws the expected exception.

⚙️ Common Mockito Methods (To Control Behavior)

MethodWhat It Doeswhen(...).thenReturn(...)Sets what the mock should return.verify(mock).method()Checks if a method was called.any(), anyString()Argument matchers used in mocks.doReturn(...).when(...)Alternative to when() (for spies).doThrow(...).when(...)Simulates throwing an exception.times(n), never(), atLeastOnce()Checks how many times a method was called.

🔍 Example: JUnit + Mockito in Action (Beginner Friendly)

Let’s write a test case for a real Java class using JUnit and Mockito.

✅ Step 1: Your Class (Service to Test)

javaCopyEditpublic class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public User registerUser(String name, String email) { if (userRepository.findByEmail(email).isPresent()) { throw new IllegalArgumentException("User already exists"); } return userRepository.save(new User(0, name, email)); } }

✅ Step 2: Your Test Class

javaCopyEdit@ExtendWith(MockitoExtension.class) public class UserServiceTest { @Mock private UserRepository userRepository; @InjectMocks private UserService userService; @Test void testRegisterUserSuccessfully() { // Arrange when(userRepository.findByEmail("[email protected]")).thenReturn(Optional.empty()); // Act User result = userService.registerUser("Test", "[email protected]"); // Assert assertEquals("Test", result.getName()); verify(userRepository).save(any(User.class)); } @Test void testRegisterUserAlreadyExists() { // Arrange when(userRepository.findByEmail("[email protected]")) .thenReturn(Optional.of(new User(1, "Old", "[email protected]"))); // Act + Assert assertThrows(IllegalArgumentException.class, () -> { userService.registerUser("New", "[email protected]"); }); verify(userRepository, never()).save(any()); } }

🎓 Why This Matters for Interviews

Java interviews don’t just test your ability to write working code — they test if you know how to:

Write clean, modular, and testable code Use JUnit and Mockito to validate your logic Work in teams where testing is standard practice

Mastering these concepts will not only help you ace interviews but also make you a confident and job-ready Java developer.

🎁 BONUS: Download Your Free Java Unit Testing Cheat Sheet

Want to keep all JUnit and Mockito annotations and methods handy?

✅ Get the complete cheat sheet ✅ Interview-ready reference ✅ Perfect for revision & practice

👉 [Click here to download your FREE PDF now]

Challenges

We will discuss about Microservice different challenges while building microservices

We will discuss about Microservice different challenges while building microservices

We will start problem no 1 : Bound context, 2. Configuration Management, 3. Dynamic Scale UP and Dynamic scale Down, 4. Visibility, 5. Pack of Cards

1. Bound context :


We said earlier we would have 5 microservices 

We said we would have 5 or 50 microservices , these microservices would have multiple instances in each environment and there are multiple environement, like dev, test, stage and prod,

These Microservices would have multiple instances see below

Lets say there 10 microservices in 5 environement 

Each Microservices has 50 instances , so we are taking about tons of configuraiton so that lots of work for operation Team to mentain.

third important challenge is dynamic scale up and dynamic scale down.


Stablishing the technology to do that, (ex kubernetes ) Load of Microservices will different on on different instances on different time 

At Perticular time might be I need two instances of particular microservices of two, but letter at different point of time might I needing 10 instances of this microservicesso I should be able to bring new instances of microservices UP and bring down older instances of mcirservices when they are realy not needed all with dynamic load balancing beacause when there is one instance of microservices1, and 4 instance of mciroserce2 , I want to dist

I want to distribuite all instance of of microservices1 , If there are 4 instance of microservices2 comming up , I would want to insure that all new one being used full extend , so we need ability to dynamicly bring new instances and also distribute the load among the new instances 

4th and most important challenge is visibility lets look in details.


If I say functionality is now distributed among 5 microservices and there is bug

How do you identify where the bug is , you have to centeralise log where you can go and find out what happen on perticular microservices on specific request shich microservices cause the problem

Not Just that we also need monitoring around these microservices because we have 100 of microservices we need to be able to identify which are microservices are down , you would want to autometically identify the the server, which they not have enough disk space all kind of this thing need to be automated.

We need great visibility into what happening to the microservices 

Last but not the least Pack of cards see next section 

If Not well desing microservices architecture , Its can be like pack of cards what do I mean

Its basically that I microservices architecture one microservices calling another calling another.

There would be the certain microservices fundamental of the whole things , If that microservices goes down then entire application go down, It's like pack of cards , you are building one on top of another and so on. There fore they can collapse very easily 

There fore its very important to have fault tolerance into your microservice 


We have seen in challenge below section in detail

  • Bounded Context : What is the right context of your microservices, what is right boundry of your microserices

  • Configuraiton Management : 100 of microservices has lot of environement , there are tons of configuraiton you would want to manage how would you simplify that

  • Dynamically Scale UP and Dynamically Down : Dynamically distribute the load among the active instance

  • Visibility : What happening around the simple microservice, A simple microservice involve multiple microservice , how do I determine which microservice cause for defect , how I would know all my microservice up and running ..

  • Pack of card : How would I prevent, Once microservices down taking down entire application, How I would Implement fault tolerance into my microservices


  • Spring Cloud

    Introduction To Spring Cloud

    Spring cloud provide various features under umbrella of spring cloud which help us to provide solutions the challenge we discussed

    Spring cloud provide multiple project to solve the problem of distributed application.


    1. Spring Cloud NetFlix

    Integrated various component 

    1. Eureka

    2. Hystrix

    3. Zull 


    2. Spring Cloud Config

    Provide Centeralize configuration management 


    3. Spring Cloud Bus

    This enable microservices and infrastrucre related component

    • Config Server
    • API gateway to talk to each other 


    Challenge Discussed and Solution provide by Spring Cloud

    1. Configuration Management

    Spring Cloud Config Server

    Lets see in detail

    We talk about Fact multiple microservices multiple environement for each of this microservices and multiple instance any of those environement, this would mean lot of configuration of these microservices that's operation team need to manage 

    Spring cloud config server provide an approach where you can store all the configuration for all the different environment of all the microservices in GIT repository , so you can store all the configuration for different environment of different microservices in just one place into centralize location 

    Spring cloud config server can be used to expose that configuration to all the microservices , this help us to keep all the configuraiton in one one place and make us to easy to maintain all the microservices configuration

    Next challenge we talk about Dynamic scale up and scale down the solution in next section


    2. Dynamic Scale UP and Down

    Naming Server

    Ribbon (Client side Load balancing)

    Feign ( Easier Rest Client)

    In Example you are looking at Microservice called CurrencyCalculationService which is talking to the CurrrencyExchangeService1 as you can see in the diagram there are multiple instances CurrencyExchangeService (currency-excahnge-service1, currency-exchange-service2 etc). It's possible that any point of time new instances can be added in or removed out. 

    We would want to currencyCalculationService to be able to distribute the load between all the instances of CurrencyExchangeService , we would want to able dynamically check what are the available instances of currencyExchangeService and make sure the load distributed among all of them The solution would be discussing , using NamingServer ( Eureka ) so all the instance of microservices would register with naming server. 

    So NamingServer(Eureka) has two Important Feature 1. ServiceRegistration(ServiceDisovery) so all microservices can register with microservices. 2. Service Discovery 

    NamingServer(Eureka)

    1. Service REgistration

    2. ServiceDiscovery.

    In This example CurrencyCalculationService can ask to EurekaNamingServer hey NamingServer give me the current instance of CurrencyExchangeService and the NamingServer would provide provide those url of CurrencyExchangeService , this help to establish dynamic relationship with CurrencyCalculationService and instance of CurrencyExchangeService 

    Ribon

    We will use Ribbon for client side load balancing that means CurrencyCalculationService will host Ribbon, It would make sure load equally distributed among the existing instances that gets from the naming server 

    Fiegn

    We also use Feign in CurrencyCalculationService as a mechanism to write simple Restfull Client 

    The Next Challenge is Visibility and Monitoring see in next section


    3. Visbilty and Monitoring
  • Zipking Distributed Tracing

  • NetFlix API Gateway

  • The Solution of Visibility and monitoring are Zipking Distributed Tracing Server , We would use spring cloud slauth to asign a id to request across multiple component , we would use zipking Distributed Tracing to trace request across multiple component 

    Important thing about microservices, Microservices have lots of common features for example logging , security analytics and etc. you would dont want to implement common feature in every microservices 

    API Gateway

    API Gateway provide greate solution to this king of challenge , we will use netflix Zull API Gateway 

    Fault Tollrence 

    If Service is down, Hystrix helps us to configure default response 

  • Hystrix


  • Advantage of Microservices

    New Technology and Process Adaption

    Its enable you to adapt new technology and process very easily

    When we build application combination of microservice which can communicate with each other using simple message, each of these microservices can be built in different technology 

    In Typical monolith applicaiton we would not have that facility, 

    For Example : Microservice1 might be in java, Microservices2 might be in python , microservices might be in nodejs microservices4 might be written in cotlin tommarow might be language xyz which is realy doing well and which provide lot of benifit to you , you can easily create microservices in that specific languagee and also for the new microservice that we create we can bring new new processes as well

    Dynamic Scalling 

    Other Important feature is dynamic scalling 

    Consider online shoping like amazon they realy don't have same amount of loads or same amount of traffic or same amount of users throught the year , specially during the holiday season load on the application will be alot and rest of the year there might be not such load . During the black friday might be the load huge amount of load , 

    Another Example : Number of the mobile network user will increase during the peak hours (7 to 10 pm) every day rest of the day load will be less.

    If your microservices cloud enabled then they can scale dynamically and you can procure hardware and release it dynamically as well 

    So you can scale up your application and scale them down based on the load because you are developing smaller microservices.

    Faster Relase Cycles

    Easer to relase microservices campare to monolithic applicaiton 

    This means that you can bring new feature faster to market, that is good feature in modern world.

    Client Side Load Balancer
  • Add dependencies

  • Feign Client

  • Create Proxy Interface and declare method

  • user proxy interface object call the method and retrive the desired microservice

  • Step1 : Add OpenFeign Dependency

    API Gateway provide greate solution to this king of challenge , we will use netflix Zull API Gateway 

    Step2 - Create Proxy interface

    If Service is down, Hystrix helps us to configure default response 

  • Hystrix

  • Step3 - Enable Feign Client : on application class of (main class)

    @EnableFeignClients

  • C

  • Lets see there is instance1 ( 8100) instance2(8200) and instance3(8300) and many more instances comming up and down automatecllay how you will mange all these dynamic instance scaling, solution we will using Service Registry in Naming server

  • Step2 - Create Proxy interface

    If Service is down, Hystrix helps us to configure default response 

    If Service is down, Hystrix helps us to configure default response 

  • Hystrix


  • Service Registery | Naming Server

    2023 Evelyn. All Rights Reserved.