I have a problem about running this test method regarding the return of booklist in JUnit Service test by using Mock.
How can I fix the issue?
I got this issue shown below.
java.lang.NullPointerException: Cannot invoke "org.springframework.data.domain.Page.getContent()" because the return value of "com.example.lib.repository.BookRepository.findAll(org.springframework.data.jpa.domain.Specification, org.springframework.data.domain.Pageable)" is null
Here is the test class shown below.
@ExtendWith(MockitoExtension.class)
public class BookListServiceTest {
@InjectMocks
private BookListService bookListService;
@Mock
private BookRepository bookRepository;
@Mock
private CategoryService categoryService;
@Test
void givenBookList_whenGetAllBooks_thenReturnBookList() {
// given - precondition or setup
BookResponse bookResponse1 = BookResponse.builder().bookStatus(BookStatus.READING)
.title("Book Title 1")
.categoryId(1L)
.build();
BookResponse bookResponse2 = BookResponse.builder().bookStatus(BookStatus.READING)
.title("Book Title 2")
.categoryId(1L)
.build();
List<BookResponse> bookListResponse = Arrays.asList(bookResponse1,bookResponse2);
Category category = Category.builder().name(CategoryType.COMIC.getValue()).build();
SaveBookRequest saveBookRequest1 = SaveBookRequest.builder().bookStatus(BookStatus.READING)
.title("Book Title 1")
.userId(1L)
.categoryId(1L)
.build();
SaveBookRequest saveBookRequest2 = SaveBookRequest.builder().bookStatus(BookStatus.READING)
.title("Book Title 2")
.userId(1L)
.categoryId(1L)
.build();
Book book1 = Book.builder().category(category)
.bookStatus(saveBookRequest1.getBookStatus())
.title(saveBookRequest1.getTitle())
.publisher(saveBookRequest1.getPublisher())
.lastPageNumber(saveBookRequest1.getLastPageNumber())
.authorName(saveBookRequest1.getAuthorName())
.totalPage(saveBookRequest1.getTotalPage())
.userId(saveBookRequest1.getUserId())
.build();
Book book2 = Book.builder().category(category)
.bookStatus(saveBookRequest2.getBookStatus())
.title(saveBookRequest2.getTitle())
.publisher(saveBookRequest2.getPublisher())
.lastPageNumber(saveBookRequest2.getLastPageNumber())
.authorName(saveBookRequest2.getAuthorName())
.totalPage(saveBookRequest2.getTotalPage())
.userId(saveBookRequest2.getUserId())
.build();
// when - action or the behaviour that we are going test
when(categoryService.loadCategory(anyLong())).thenReturn(category);
when(bookRepository.save(any(Book.class))).thenReturn(book1);
when(bookRepository.save(any(Book.class))).thenReturn(book2);
when(
bookRepository.findAll(BookListServiceTest.BookSearchSpecification.searchByUserBooks(1L), PageRequest.of(1,10))
.getContent() // HERE IS THE ISSUE
.stream()
.map(BookListServiceTest::convertResponse)
.collect(Collectors.toList())
).thenReturn(bookListResponse);
// then - verify the output
List<BookResponse> bookListResponseResult = bookListService.listBooks(10,1,1L); // HERE IS THE ISSUE
assertEquals(bookListResponse.get(0).getCategoryId(), bookListResponseResult.get(0).getCategoryId());
assertEquals(bookListResponse.get(0).getTitle(), bookListResponseResult.get(0).getTitle());
assertEquals(bookListResponse.get(1).getCategoryId(), bookListResponseResult.get(1).getCategoryId());
assertEquals(bookListResponse.get(1).getTitle(), bookListResponseResult.get(1).getTitle());
}
private static class BookSearchSpecification {
public static Specification<Book> searchByUserBooks(Long userId) {
return (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("userId"), userId);
}
}
private static BookResponse convertResponse(Book model) {
return BookResponse.builder()
.authorName(model.getAuthorName())
.title(model.getTitle())
.imageUrl(model.getImage() != null ? model.getImage().getImageUrl() : null)
.build();
}
}
CodePudding user response:
so it is pretty simple what is wrong with your issue. You are telling your test to mock method:
bookRepository.findAll(BookListServiceTest.BookSearchSpecification.searchByUserBooks(1L), PageRequest.of(1,10))
.getContent()
.stream()
.map(BookListServiceTest::convertResponse)
.collect(Collectors.toList())
but you are NOT mocking method
bookRepository.findAll(BookListServiceTest.BookSearchSpecification.searchByUserBooks(1L), PageRequest.of(1,10))
hence it always returns null. If you mock the foregoing method correctly, you ought to solve your issue. I cannot post what exactly, because I do not know what the method returns, but I presume it will be something like
Page<Book>
So your method could probably look like this:
when(bookRepository.findAll(BookListServiceTest.BookSearchSpecification.searchByUserBooks(1L), PageRequest.of(1,10)))
.thenReturn(new PageImpl<Book>(new Arraylist<Book>()));
CodePudding user response:
After I revised that line, the issue disappeared.
Change
when(
bookRepository.findAll(BookListServiceTest.BookSearchSpecification.searchByUserBooks(1L), PageRequest.of(1,10))
.getContent()
.stream()
.map(BookListServiceTest::convertResponse)
.collect(Collectors.toList())
).thenReturn(bookListResponse);
to
when(
bookRepository.findAll(any(Specification.class), any(Pageable.class))
).thenReturn(new PageImpl<Book>(Arrays.asList(book1,book2)));