Introduction :#
Mockito is a Java testing framework used to create mock objects, which allow developers to isolate and test specific units of code without relying on external dependencies like databases or web services. It is often used with JUnit to test interactions between objects by simulating behaviors and verifying method calls.
For example, Mockito lets you:
- Mock objects to simulate their behavior.
- Stub methods to return specific values.
- Verify interactions to ensure methods are called with expected arguments.
This helps ensure that your code works as expected in isolation, leading to more reliable and faster unit tests.
Mockito#
Mockito is useful for testing components in isolation without relying on their actual implementations or external dependencies. Mockito can be used for: • Mocking: Creating mock objects to simulate the behavior of real objects. • Stubbing: Defining the behavior of mock objects when specific methods are called. • Verification: Checking if certain methods were called on mock objects
Real Life Analogy#
Imagine you are testing a car's navigation system, but you don't want to actually drive the car or use real GPS satellites every time you run a test. Instead, you mock the GPS signal to simulate different locations and routes. This allows you to test how the navigation system reacts without needing the actual GPS system or a physical car.
In the same way, Mockito lets you mock dependencies in your code. For example, if you have a UserService
class that depends on a UserRepository
to fetch users from a database, you can mock the UserRepository
so that, instead of making a real database call, it returns pre-defined data. This allows you to test the behavior of UserService
without involving the actual database.
Real-Life Analogy with Mockito Terms:#
- Mocking: Pretending to have a real GPS signal (or other service) without actually using the real one.
- Stubbing: Telling the GPS to always say you are at a specific location.
- Verifying: Checking if the navigation system asked the GPS for your current location.
This approach makes testing easier, faster, and more focused on the component you're testing (in this case, the navigation system). Similarly, Mockito makes unit testing in code more isolated and efficient.
Mockito Methods#
Mockito methods and techniques help create flexible and robust unit tests by simulating real interactions without relying on actual implementations.
- Creating Mock:
- With
@Mock
Annotation: Automatically injects a mock object. - With
Mockito.mock(Classname)
: Manually creates a mock object.
- With
- Stubbing Mock:
when(T methodCall)
: Specifies a method call to be stubbed.thenReturn(T value)
: Sets a return value for a stubbed method call.thenThrow(Throwable... throwables)
: Throws an exception when a stubbed method call is made.
- Verifying Methods:
verify(T mock)
: Verifies that a method was called on a mockverify(T mock, VerificationMode mode)
: Verifies a method was called with a specific verification mode.- Verification Modes:
times(int wantedNumberOfInvocations)
: Verifies the exact number of method invocations.never()
: Verifies that a method was never called.atLeastOnce()
: Verifies that a method was called at least once.atLeast(int minNumberOfInvocations)
: Verifies that a method was called at least a specified number of times.atMost(int maxNumberOfInvocations)
: Verifies that a method was called no more than a specified number of times.only()
: Verifies that no other method was called on the mock.
- Argument Captor:
- Captures arguments passed to a method call for further assertions or validation.
Implementation and Explanation#
- Code
- Go to the Service class.
- Press CTRL + SHIFT + T and create a Test file and implements and tests all method.
- Explanation
This unit test is for the EmployeeService
class, specifically testing the getEmployeeById
and createNewEmployee
methods using Mockito for mocking dependencies. Here's a detailed breakdown of the code:
- Test Setup
- Annotations:
@ExtendWith(MockitoExtension.class)
: This annotation integrates Mockito with JUnit 5. It initializes mocks, spies, and injects them into the test class.@Import(TestContainerConfiguration.class)
: This imports the configuration needed to set up Testcontainers for database integration.@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
: This tells Spring Boot not to replace the database configuration with an in-memory database. Instead, it uses the database provided by Testcontainers.
- Fields:
@Mock
: Creates a mock instance ofEmployeeRepository
. Mocks are used to simulate the behavior of real objects and control their responses.@Spy
: Creates a spy instance ofModelMapper
. Spies allow partial mocking, meaning you can call real methods while still controlling certain aspects.@InjectMocks
: Creates an instance ofEmployeeService
and injects the mocks and spies into it.
- Annotations:
- Setup Method
- @BeforeEach: This method runs before each test. It initializes mockEmployeeEntity and mockEmployeeDto with some default values that will be used in the tests.
- Test Methods
- Testing
getEmployeeById()
:
- Testing
- Explanation
- Assign: Sets up the mock repository to return
mockEmployeeEntity
whenfindById(id)
is called. - Act: Calls the
getEmployeeById
method ofemployeeService
. - Assert: Verifies that the returned
EmployeeDto
is not null and has the expected values. - Verify: Checks that
findById(id)
was called exactly once.
- Assign: Sets up the mock repository to return
- Testing
createNewEmployee()
:- Code
- Explanation
- Assign:
- Sets up the mock repository to return an empty list when
findByEmail
is called, simulating no existing employee with the given email. - Configures
save
to returnmockEmployeeEntity
when called.
- Sets up the mock repository to return an empty list when
- Act: Calls
createNewEmployee
withmockEmployeeDto
to test employee creation. - Assert:
- Checks that the returned
EmployeeDto
is not null and its email matchesmockEmployeeDto
's email. - Uses
ArgumentCaptor
to capture the argument passed tosave
and verifies that the capturedEmployeeEntity
has the expected email.
- Checks that the returned
- Verify: Ensures that the
save
method was called once and captures the argument used in that call.
- Assign:
- Output
Here, we are testing whether the Service
class is functioning correctly.
Here, we have already covered these aspects, which are highlighted in green in the image.