🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
Introduction
The @InjectMocks annotation in Mockito is used to automatically inject mock objects into the object being tested. This is particularly useful when the class under test has dependencies that need to be mocked. Instead of manually injecting these mock objects, you can use @InjectMocks to automatically inject all the mocks marked with @Mock or @Spy into the tested object. In this tutorial, we will demonstrate step-by-step how to use the @InjectMocks annotation in Mockito.
Maven Dependencies
To use Mockito with JUnit 5, add the following dependencies to your pom.xml file:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
Example Scenario
We will create an OrderService class that has a dependency on an OrderRepository and a NotificationService. Our goal is to test the OrderService methods using Mockito to mock the dependencies and inject them using the @InjectMocks annotation.
OrderService, OrderRepository, and NotificationService Classes
First, create the Order, OrderRepository, and NotificationService classes.
public class Order {
private String orderId;
private String product;
private int quantity;
// Constructor, getters, and setters
}
public interface OrderRepository {
Order findOrderById(String orderId);
void saveOrder(Order order);
}
public class NotificationService {
public void notifyCustomer(String message) {
// Code to notify customer
}
}
Create the OrderService class that depends on the OrderRepository and NotificationService.
public class OrderService {
private final OrderRepository orderRepository;
private final NotificationService notificationService;
public OrderService(OrderRepository orderRepository, NotificationService notificationService) {
this.orderRepository = orderRepository;
this.notificationService = notificationService;
}
public Order getOrder(String orderId) {
return orderRepository.findOrderById(orderId);
}
public void placeOrder(Order order) {
orderRepository.saveOrder(order);
notificationService.notifyCustomer("Order placed: " + order.getOrderId());
}
}
JUnit 5 Test Class with Mockito
Create a test class for OrderService using JUnit 5 and Mockito.
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(MockitoExtension.class)
public class OrderServiceTest {
@Mock
private OrderRepository orderRepository;
@Mock
private NotificationService notificationService;
@InjectMocks
private OrderService orderService;
@Test
public void testGetOrder() {
// Given
Order mockOrder = new Order("1", "Laptop", 1);
when(orderRepository.findOrderById("1")).thenReturn(mockOrder);
// When
Order result = orderService.getOrder("1");
// Then
assertNotNull(result);
assertEquals("1", result.getOrderId());
assertEquals("Laptop", result.getProduct());
assertEquals(1, result.getQuantity());
verify(orderRepository).findOrderById("1");
}
@Test
public void testPlaceOrder() {
// Given
Order newOrder = new Order("2", "Smartphone", 2);
// When
orderService.placeOrder(newOrder);
// Then
verify(orderRepository).saveOrder(newOrder);
verify(notificationService).notifyCustomer("Order placed: 2");
}
}
Explanation
Annotations:
@ExtendWith(MockitoExtension.class): Integrates Mockito with JUnit 5, enabling the use of Mockito annotations.@Mock: Creates mock instances of theOrderRepositoryandNotificationServiceclasses.@InjectMocks: Injects the mock instances into theOrderServiceinstance.
Given:
Order mockOrder = new Order("1", "Laptop", 1);: Creates a mockOrderobject.when(orderRepository.findOrderById("1")).thenReturn(mockOrder);: Configures the mockOrderRepositoryto return the mockOrderwhen thefindOrderByIdmethod is called with the argument "1".
When:
Order result = orderService.getOrder("1");: Calls thegetOrdermethod on theOrderServiceinstance.orderService.placeOrder(newOrder);: Calls theplaceOrdermethod on theOrderServiceinstance with a newOrder.
Then:
assertNotNull(result);: Asserts that the result is not null.assertEquals("1", result.getOrderId());: Asserts that the order ID of the returnedOrderis "1".assertEquals("Laptop", result.getProduct());: Asserts that the product of the returnedOrderis "Laptop".assertEquals(1, result.getQuantity());: Asserts that the quantity of the returnedOrderis 1.verify(orderRepository).findOrderById("1");: Verifies that thefindOrderByIdmethod was called with the expected argument.verify(orderRepository).saveOrder(newOrder);: Verifies that thesaveOrdermethod was called with the newOrder.verify(notificationService).notifyCustomer("Order placed: 2");: Verifies that thenotifyCustomermethod was called with the expected message.
Conclusion
The @InjectMocks annotation in Mockito simplifies the injection of mock objects into the class under test. By using @Mock and @InjectMocks, you can easily set up mock dependencies and focus on testing the behavior of your code. This step-by-step guide demonstrated how to effectively use the @InjectMocks annotation in your unit tests, covering different scenarios to ensure comprehensive testing of the OrderService class.
Comments
Post a Comment
Leave Comment