Introduction
In this chapter, we will learn about the @MockBean
annotation in Mockito, specifically within the context of Spring Boot applications. The @MockBean
annotation is used to create and inject mock objects into the Spring application context, making it particularly useful for integration tests where you need to mock out certain beans.
Key Points about the @MockBean Annotation
- Spring Context Integration: The
@MockBean
annotation is used to add mocks to the Spring application context. - Overrides Existing Beans: It can override existing beans of the same type in the application context.
- Useful for Integration Tests: Particularly useful for integration tests where you want to mock out certain dependencies.
- Initialization: Managed by the Spring TestContext framework.
Setting Up Mockito and Spring Boot for @MockBean Annotation
Ensure that you have the necessary dependencies in your pom.xml
if you are using Maven:
<dependencies>
<!-- Mockito Core dependency -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<!-- Spring Boot Starter Test dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>3.1.2</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- H2 Database dependency -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
Example: Using @MockBean Annotation
Description
In this example, we will create a BookService
class that depends on a BookRepository
class. The BookService
class will use the BookRepository
class to fetch book details. We will create an integration test for the BookService
class using Mockito’s @MockBean
annotation to mock the BookRepository
.
Class Under Test: BookService
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BookService {
private final BookRepository bookRepository;
@Autowired
public BookService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
public Book getBookDetails(String isbn) {
return bookRepository.findByIsbn(isbn);
}
}
Supporting Class: BookRepository
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, Long> {
Book findByIsbn(String isbn);
}
Entity Class: Book
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
public class Book {
@Id
private Long id;
private String isbn;
private String title;
private String author;
// getters and setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
Test Class: BookServiceTest
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
public class BookServiceTest {
@MockBean
private BookRepository bookRepository;
@Autowired
private BookService bookService;
@Test
void testGetBookDetails() {
// Arrange
Book book = new Book();
book.setIsbn("1234567890");
book.setTitle("Mockito in Action");
book.setAuthor("John Doe");
when(bookRepository.findByIsbn("1234567890")).thenReturn(book);
// Act
Book result = bookService.getBookDetails("1234567890");
// Assert
assertNotNull(result);
assertEquals("Mockito in Action", result.getTitle());
assertEquals("John Doe", result.getAuthor());
}
}
Explanation
- MockBean Annotation:
@MockBean private BookRepository bookRepository;
The
@MockBean
annotation creates a mock object for theBookRepository
class and injects it into the Spring application context. This mock will override any existing bean of the same type. - Autowired Annotation:
@Autowired private BookService bookService;
The
@Autowired
annotation injects theBookService
bean from the Spring application context. TheBookService
bean will use the mockedBookRepository
. - Test Method:
@Test void testGetBookDetails() { // Arrange Book book = new Book(); book.setIsbn("1234567890"); book.setTitle("Mockito in Action"); book.setAuthor("John Doe"); when(bookRepository.findByIsbn("1234567890")).thenReturn(book); // Act Book result = bookService.getBookDetails("1234567890"); // Assert assertNotNull(result); assertEquals("Mockito in Action", result.getTitle()); assertEquals("John Doe", result.getAuthor()); }
This test method sets up the mock behavior (Arrange), calls the method under test (Act), and checks the expected results (Assert). It verifies that the
BookRepository
mock is used by theBookService
to fetch book details.
Conclusion
The @MockBean
annotation in Mockito is used for creating and injecting mock objects into the Spring application context. It simplifies the setup of integration tests by allowing you to mock out specific beans. This approach helps ensure that your Spring Boot application works correctly with mocked dependencies, making your tests more reliable and maintainable.