Merge pull request #16034 from TanyaOhotnik/BAEL-7238
BAEL-7238 Inject mock into Spy object in Mockito
This commit is contained in:
commit
f82778cc17
|
@ -24,11 +24,18 @@
|
|||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<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>
|
||||
|
||||
</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