Mockito @MockBean Annotation

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

  1. MockBean Annotation:
    @MockBean
    private BookRepository bookRepository;
    

    The @MockBean annotation creates a mock object for the BookRepository class and injects it into the Spring application context. This mock will override any existing bean of the same type.

  2. Autowired Annotation:
    @Autowired
    private BookService bookService;
    

    The @Autowired annotation injects the BookService bean from the Spring application context. The BookService bean will use the mocked BookRepository.

  3. 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 the BookService 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.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top