🎓 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
BDDMockito.given() is a method provided by Mockito to support the Behavior-Driven Development (BDD) style of writing tests. It is used to set up mock objects with predefined behaviors, making the tests more readable and expressive. This tutorial will demonstrate how to use BDDMockito.given() to stub methods in a BDD style.
Maven Dependencies
To use Mockito with JUnit 5 and enable BDDMockito syntax, 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 a LibraryService class that has a dependency on a BookRepository. Our goal is to test the LibraryService methods using BDDMockito.given() to handle stubbing.
LibraryService and BookRepository Classes
First, create the Book class, the BookRepository interface, and the LibraryService class.
public class Book {
private String title;
private String author;
// Constructor, getters, and setters
public Book(String title, String author) {
this.title = title;
this.author = author;
}
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;
}
}
public interface BookRepository {
void saveBook(Book book);
Book findBookByTitle(String title);
List<Book> findAllBooks();
}
public class LibraryService {
private final BookRepository bookRepository;
public LibraryService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
public void addBook(String title, String author) {
Book book = new Book(title, author);
bookRepository.saveBook(book);
}
public Book getBookByTitle(String title) {
return bookRepository.findBookByTitle(title);
}
public List<Book> getAllBooks() {
return bookRepository.findAllBooks();
}
}
JUnit 5 Test Class with BDDMockito
Create a test class for LibraryService using JUnit 5 and BDDMockito.
import static org.mockito.BDDMockito.*;
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;
import java.util.Arrays;
import java.util.List;
@ExtendWith(MockitoExtension.class)
public class LibraryServiceTest {
@Mock
private BookRepository bookRepository;
@InjectMocks
private LibraryService libraryService;
@Test
public void testAddBook() {
// Given
String title = "Mockito in Action";
String author = "Ramesh Fadatare";
// When
libraryService.addBook(title, author);
// Then
then(bookRepository).should().saveBook(any(Book.class));
}
@Test
public void testGetBookByTitle() {
// Given
String title = "Mockito in Action";
Book book = new Book(title, "Ramesh Fadatare");
given(bookRepository.findBookByTitle(title)).willReturn(book);
// When
Book result = libraryService.getBookByTitle(title);
// Then
assertNotNull(result);
assertEquals(title, result.getTitle());
assertEquals("Ramesh Fadatare", result.getAuthor());
}
@Test
public void testGetAllBooks() {
// Given
Book book1 = new Book("Mockito in Action", "Ramesh Fadatare");
Book book2 = new Book("Effective Java", "Joshua Bloch");
List<Book> books = Arrays.asList(book1, book2);
given(bookRepository.findAllBooks()).willReturn(books);
// When
List<Book> result = libraryService.getAllBooks();
// Then
assertNotNull(result);
assertEquals(2, result.size());
assertEquals("Mockito in Action", result.get(0).getTitle());
assertEquals("Effective Java", result.get(1).getTitle());
}
@Test
public void testAddBookWithCustomMatcher() {
// Given
String title = "Mockito in Action";
String author = "Ramesh Fadatare";
// When
libraryService.addBook(title, author);
// Then
then(bookRepository).should().saveBook(argThat(book -> book.getTitle().equals("Mockito in Action") && book.getAuthor().equals("Ramesh Fadatare")));
}
}
Explanation
Creating Mocks with
@Mock:- The
@Mockannotation creates a mock instance of theBookRepositoryinterface. This mock instance can be used to simulate the behavior of theBookRepositoryin a controlled way.
- The
Injecting Mocks with
@InjectMocks:- The
@InjectMocksannotation injects the mockBookRepositoryinto theLibraryServiceinstance to provide a controlled test environment. This allows theLibraryServicemethods to be tested in isolation from the actualBookRepositoryimplementation.
- The
Using BDDMockito:
given(): Thegiven(bookRepository.findBookByTitle(title)).willReturn(book);method configures the mockBookRepositoryto return a specificBookobject when thefindBookByTitlemethod is called with the specified title.then(): Thethen(bookRepository).should().saveBook(any(Book.class));method verifies that thesaveBookmethod was called on theBookRepositorywith anyBookobject.argThat(): Thethen(bookRepository).should().saveBook(argThat(book -> book.getTitle().equals("Mockito in Action") && book.getAuthor().equals("Ramesh Fadatare")));method verifies that thesaveBookmethod was called on theBookRepositorywith aBookobject that matches the specified title and author.
Additional Scenarios
Scenario: Handling Exceptions with BDDMockito
In this scenario, we will demonstrate how to handle exceptions using BDDMockito.
@Test
public void testGetBookByTitleThrowsException() {
// Given
String title = "Nonexistent Book";
given(bookRepository.findBookByTitle(title)).willThrow(new RuntimeException("Book not found"));
// When & Then
RuntimeException exception = assertThrows(RuntimeException.class, () -> {
libraryService.getBookByTitle(title);
});
assertEquals("Book not found", exception.getMessage());
}
Explanation
- Handling Exceptions with BDDMockito:
- The
given(bookRepository.findBookByTitle(title)).willThrow(new RuntimeException("Book not found"));method configures the mockBookRepositoryto throw aRuntimeExceptionwhen thefindBookByTitlemethod is called with the specified title. This allows thegetBookByTitlemethod of theLibraryServiceclass to be tested with controlled exception handling behavior.
- The
Scenario: Verifying No Interactions
In this scenario, we will demonstrate how to verify that no interactions occurred with the mock object using BDDMockito.
@Test
public void testNoInteractionsWithBookRepository() {
// Given
// No interactions expected
// When
// No method calls
// Then
then(bookRepository).shouldHaveNoInteractions();
}
Explanation
- Verifying No Interactions:
- The
then(bookRepository).shouldHaveNoInteractions();method verifies that no interactions occurred with theBookRepositorymock object. This ensures that theBookRepositorywas not used during the test.
- The
Conclusion
Using BDDMockito.given() in Mockito allows you to write more readable and expressive tests that follow the Behavior-Driven Development (BDD) style. By using given() for stubbing methods, you can handle various scenarios and control the behavior of mock objects. This step-by-step guide demonstrated how to effectively use BDDMockito.given() in your unit tests, covering different scenarios to ensure comprehensive testing of the LibraryService class.
Related Mockito BDDMockito Class Methods (Behavior-Driven Development Style)
Mockito BDDMockito
Mockito BDDMockito given()
Mockito BDDMockito willThrow()
Mockito BDDMockito willAnswer()
Mockito BDDMockito willReturn()
Mockito BDDMockito willDoNothing()
Mockito BDDMockito willCallRealMethod()
Mockito BDDMockito then()
Mockito BDDMockito.any()
Mockito BDDMockito.times()
Comments
Post a Comment
Leave Comment