BAEL-7238 Inject mock into Spy object in Mockito
- added "library" service to demonstrate mockito injection features - updated mockito version to 5.10
This commit is contained in:
parent
4f0a8ce5d9
commit
5c18b2e7f7
|
@ -24,11 +24,18 @@
|
||||||
<version>${mockito.version}</version>
|
<version>${mockito.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<mockito-inline.version>4.8.1</mockito-inline.version>
|
<mockito-inline.version>4.8.1</mockito-inline.version>
|
||||||
<mockito.version>5.9.0</mockito.version>
|
<mockito.version>5.10.0</mockito.version>
|
||||||
|
<lombok.version>1.18.30</lombok.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.baeldung.injectmockintospy;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Book {
|
||||||
|
private String name;
|
||||||
|
private String author;
|
||||||
|
private long timesTaken;
|
||||||
|
private ZonedDateTime returnDate;
|
||||||
|
|
||||||
|
public Book(String name, String author, long timesTaken) {
|
||||||
|
this.name = name;
|
||||||
|
this.author = author;
|
||||||
|
this.timesTaken = timesTaken;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.baeldung.injectmockintospy;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class BookControlService {
|
||||||
|
|
||||||
|
private StatisticService statisticService;
|
||||||
|
private RepairService repairService;
|
||||||
|
|
||||||
|
public void returnBook(Book book) {
|
||||||
|
book.setReturnDate(null);
|
||||||
|
statisticService.calculateAdded();
|
||||||
|
if(repairService.shouldRepair(book)){
|
||||||
|
log.info("Book should be repaired");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void giveBook(Book book) {
|
||||||
|
book.setReturnDate(ZonedDateTime.now().plusDays(14L));
|
||||||
|
statisticService.calculateRemoved();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BookControlService(StatisticService statisticService, RepairService repairService) {
|
||||||
|
this.statisticService = statisticService;
|
||||||
|
this.repairService = repairService;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.baeldung.injectmockintospy;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class BookStorageService {
|
||||||
|
|
||||||
|
private BookControlService bookControlService;
|
||||||
|
private final List<Book> availableBooks = new LinkedList<>();
|
||||||
|
|
||||||
|
public BookStorageService(BookControlService bookControlService) {
|
||||||
|
this.bookControlService = bookControlService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void returnBook(Book book) {
|
||||||
|
availableBooks.add(book);
|
||||||
|
bookControlService.returnBook(book);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void giveBook(Book book) {
|
||||||
|
availableBooks.remove(book);
|
||||||
|
bookControlService.giveBook(book);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.injectmockintospy;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class RepairService {
|
||||||
|
|
||||||
|
public boolean shouldRepair(Book book) {
|
||||||
|
return book.getTimesTaken() > 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.injectmockintospy;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class StatisticService {
|
||||||
|
|
||||||
|
private long todaysActions;
|
||||||
|
|
||||||
|
public void calculateAdded() {
|
||||||
|
todaysActions++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void calculateRemoved() {
|
||||||
|
todaysActions--;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
todaysActions = 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.injectmockintospy;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class MultipleInjectMockAndManualSpyWithExtensionUnitTest {
|
||||||
|
@InjectMocks
|
||||||
|
private BookStorageService bookStorageService;
|
||||||
|
@InjectMocks
|
||||||
|
private BookControlService bookControlService = Mockito.spy(BookControlService.class);
|
||||||
|
@Mock
|
||||||
|
private StatisticService statisticService;
|
||||||
|
@Mock
|
||||||
|
private RepairService repairService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenInjectMockUsedWithManualSpy_thenMockitoCanInjectMocks() {
|
||||||
|
Book book = new Book("Some name", "Some author", 355);
|
||||||
|
bookStorageService.returnBook(book);
|
||||||
|
|
||||||
|
Assertions.assertEquals(1, bookStorageService.getAvailableBooks().size());
|
||||||
|
Mockito.verify(bookControlService).returnBook(book);
|
||||||
|
Mockito.verify(statisticService).calculateAdded();
|
||||||
|
Mockito.verify(repairService).shouldRepair(book);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.injectmockintospy;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
public class MultipleInjectMockAndManualSpyWithOpenMocksUnitTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private BookStorageService bookStorageService;
|
||||||
|
@InjectMocks
|
||||||
|
private BookControlService bookControlService;
|
||||||
|
@Mock
|
||||||
|
private StatisticService statisticService;
|
||||||
|
@Mock
|
||||||
|
private RepairService repairService;
|
||||||
|
private AutoCloseable closeable;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void openMocks() {
|
||||||
|
bookControlService = Mockito.spy(BookControlService.class);
|
||||||
|
closeable = MockitoAnnotations.openMocks(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void releaseMocks() throws Exception {
|
||||||
|
closeable.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenInjectMockUsedWithManualSpy_thenMockitoCanInjectMocks() {
|
||||||
|
Book book = new Book("Some name", "Some author", 355);
|
||||||
|
bookStorageService.returnBook(book);
|
||||||
|
|
||||||
|
Assertions.assertEquals(1, bookStorageService.getAvailableBooks().size());
|
||||||
|
|
||||||
|
Mockito.verify(bookControlService).returnBook(book);
|
||||||
|
Mockito.verify(statisticService).calculateAdded();
|
||||||
|
Mockito.verify(repairService).shouldRepair(book);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.injectmockintospy;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class MultipleInjectMockAndMockitoSpyDoesnotWorkUnitTest {
|
||||||
|
@InjectMocks
|
||||||
|
private BookStorageService bookStorageService;
|
||||||
|
@InjectMocks
|
||||||
|
@Spy
|
||||||
|
private BookControlService bookControlService;
|
||||||
|
@Mock
|
||||||
|
private StatisticService statisticService;
|
||||||
|
@Mock
|
||||||
|
private RepairService repairService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled("test is not intended to work, it is here to show that such mock setup doesn't work")
|
||||||
|
void whenInjectMockUsedWithMockitoSpy_thenMockitoCannotInjectObjectProperly() {
|
||||||
|
Book book = new Book("Some name", "Some author", 355);
|
||||||
|
bookStorageService.returnBook(book);
|
||||||
|
|
||||||
|
Assertions.assertEquals(1, bookStorageService.getAvailableBooks().size());
|
||||||
|
Mockito.verify(bookControlService).returnBook(book);
|
||||||
|
Mockito.verify(statisticService).calculateAdded();
|
||||||
|
Mockito.verify(repairService).shouldRepair(book);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.baeldung.injectmockintospy;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class SingleInjectMockAndAnnotatedSpyUnitTest {
|
||||||
|
@Spy
|
||||||
|
@InjectMocks
|
||||||
|
private BookControlService bookControlService;
|
||||||
|
@Mock
|
||||||
|
private StatisticService statisticService;
|
||||||
|
@Spy
|
||||||
|
private RepairService repairService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenOneInjectMockWithSpy_thenHierarchySuccessfullyInitialized() {
|
||||||
|
Book book = new Book("Some name", "Some author", 355, ZonedDateTime.now());
|
||||||
|
bookControlService.returnBook(book);
|
||||||
|
|
||||||
|
Assertions.assertNull(book.getReturnDate());
|
||||||
|
Mockito.verify(statisticService).calculateAdded();
|
||||||
|
Mockito.verify(repairService).shouldRepair(book);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.injectmockintospy;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class SingleInjectMockAndManualSpyWithReflectionUnitTest {
|
||||||
|
@InjectMocks
|
||||||
|
private BookStorageService bookStorageService;
|
||||||
|
@Mock
|
||||||
|
private StatisticService statisticService;
|
||||||
|
@Mock
|
||||||
|
private RepairService repairService;
|
||||||
|
private BookControlService bookControlService;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void openMocks() throws Exception {
|
||||||
|
bookControlService = Mockito.spy(new BookControlService(statisticService, repairService));
|
||||||
|
injectSpyToTestedMock(bookStorageService, bookControlService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void injectSpyToTestedMock(BookStorageService bookStorageService, BookControlService bookControlService) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field bookControlServiceField = BookStorageService.class.getDeclaredField("bookControlService");
|
||||||
|
bookControlServiceField.setAccessible(true);
|
||||||
|
bookControlServiceField.set(bookStorageService, bookControlService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenManualSpyInjectedToTestesClass_thenHierarchySuccessfullyInitialized() {
|
||||||
|
Book book = new Book("Some name", "Some author", 355);
|
||||||
|
bookStorageService.returnBook(book);
|
||||||
|
|
||||||
|
Assertions.assertEquals(1, bookStorageService.getAvailableBooks().size());
|
||||||
|
Mockito.verify(bookControlService).returnBook(book);
|
||||||
|
Mockito.verify(statisticService).calculateAdded();
|
||||||
|
Mockito.verify(repairService).shouldRepair(book);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue