Home > Enterprise >  Spring Boot Junit Mockito org.springframework.data.domain.Page.getContent() Issue
Spring Boot Junit Mockito org.springframework.data.domain.Page.getContent() Issue

Time:10-04

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>()));

check https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/PageImpl.html

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)));
  • Related