Java数据分页方法可单元测试点及新手测试实现疑问
Let's break this down step by step since you're new to unit testing—we'll cover all the testable parts of your method and clear up your confusion around the Page object.
1. What Parts of Your Method Should You Test?
Here are all the critical behaviors you should validate with unit tests:
- Default Sorting Logic: Verify that when
sortFieldorsortDirectionisnull, the method uses the defaultDESCsort onaddedOn. - Custom Sorting Application: Confirm that when valid
sortFieldandsortDirectionvalues are passed, the method correctly applies that sorting to thePageRequest. - Page Number Conversion: Your method converts the 1-based
pageparameter to 0-based forPageRequest.of()—test that this conversion works (e.g., input page=1 becomes 0, page=2 becomes 1). - DTO Mapping: Ensure every
Beneficiaryfrom the repository'sPageis correctly converted to aBeneficiaryResponseDTO, and the count of DTOs matches the page's content size. - Pagination Response Encapsulation: Validate that the returned
ListBeneficiaryResponseDTOhas accurate values for:totalPages: Matches thePage's total pagestotalElements: Matches thePage's total elementsnumber: Matches the 0-based page number from thePage- The DTO list content matches the converted beneficiaries
- (Optional) Logging: If you want to ensure the info log is triggered, you can verify
LOGGER.info("Inside getBeneficiaryOfMerchants method")is called.
2. Clarifying the Page Object in Your Test
When you create a PageImpl with just the list of beneficiaries (like new PageImpl<>(beneficiaryList)), here's what happens:
getContent()returns exactly the list you passed (so 2 entries in your example)totalElementsis set to the size of your list (2)totalPagesis 1 (since there's only one page of data with your list)number(current page index) is 0 (since the defaultPageableis unpaged)
If you want to simulate a more realistic pagination scenario (e.g., total 5 beneficiaries, page size 2, current page 1), use the full PageImpl constructor that accepts a Pageable and total elements:
// Simulate page 0 (1-based page 1) with 2 items, total 5 items Pageable pageable = PageRequest.of(0, 2); Page<Beneficiary> beneficiaries = new PageImpl<>(beneficiaryList, pageable, 5);
This way, totalPages will be 3 (5/2 rounded up), totalElements is 5, and number is 0.
3. Complete Test Example
Here's a refined version of your test that covers multiple key points:
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import java.util.ArrayList; import java.util.List; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) public class BeneficiaryServiceTest { @Mock private BeneficiaryRepository beneficiaryRepository; @InjectMocks private BeneficiaryService beneficiaryService; private Beneficiary getBeneficiary() { // Replace with your actual Beneficiary object creation logic Beneficiary ben = new Beneficiary(); ben.setId(1L); ben.setAddedOn(new java.util.Date()); return ben; } @Test public void testGetBeneficiariesOfMerchant_ValidRequest_ReturnsCorrectPagination() { // Arrange Long merchantId = 2L; int page = 1; int pageSize = 2; List<Beneficiary> beneficiaryList = new ArrayList<>(); beneficiaryList.add(getBeneficiary()); beneficiaryList.add(getBeneficiary()); // Create a Page with realistic pagination metadata Pageable expectedPageable = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Direction.DESC, "addedOn")); Page<Beneficiary> mockPage = new PageImpl<>(beneficiaryList, expectedPageable, 5); // Total 5 elements when(beneficiaryRepository.findAllByMerchantId(eq(merchantId), eq(expectedPageable))) .thenReturn(mockPage); // Act ListBeneficiaryResponseDTO response = beneficiaryService.getBeneficiaryOfMerchants( merchantId, page, pageSize, "DESC", "addedOn"); // Assert // Verify DTO list size matches page content assertEquals(2, response.getBenResonseDtoList().size()); // Verify pagination metadata is correct assertEquals(3, response.getTotalPages()); // 5 total elements / 2 per page = 3 pages assertEquals(5, response.getTotalElements()); assertEquals(0, response.getNumber()); // 0-based page index // Verify repository was called with the correct parameters verify(beneficiaryRepository, times(1)).findAllByMerchantId(eq(merchantId), eq(expectedPageable)); } @Test public void testGetBeneficiariesOfMerchant_NullSortParams_UsesDefaultSort() { // Arrange Long merchantId = 2L; List<Beneficiary> beneficiaryList = List.of(getBeneficiary()); // Default sort is DESC on addedOn Sort defaultSort = Sort.by(Sort.Direction.DESC, "addedOn"); Pageable expectedPageable = PageRequest.of(0, 10, defaultSort); Page<Beneficiary> mockPage = new PageImpl<>(beneficiaryList, expectedPageable, 1); when(beneficiaryRepository.findAllByMerchantId(eq(merchantId), eq(expectedPageable))) .thenReturn(mockPage); // Act: Pass null for sortDirection and sortField ListBeneficiaryResponseDTO response = beneficiaryService.getBeneficiaryOfMerchants( merchantId, 1, 10, null, null); // Assert assertNotNull(response); verify(beneficiaryRepository, times(1)).findAllByMerchantId(eq(merchantId), eq(expectedPageable)); } }
内容的提问来源于stack exchange,提问作者Sandeepan Nath

