You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java数据分页方法可单元测试点及新手测试实现疑问

Testing Your Java Pagination Method: Key Test Points & Page Object Clarification

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 sortField or sortDirection is null, the method uses the default DESC sort on addedOn.
  • Custom Sorting Application: Confirm that when valid sortField and sortDirection values are passed, the method correctly applies that sorting to the PageRequest.
  • Page Number Conversion: Your method converts the 1-based page parameter to 0-based for PageRequest.of()—test that this conversion works (e.g., input page=1 becomes 0, page=2 becomes 1).
  • DTO Mapping: Ensure every Beneficiary from the repository's Page is correctly converted to a BeneficiaryResponseDTO, and the count of DTOs matches the page's content size.
  • Pagination Response Encapsulation: Validate that the returned ListBeneficiaryResponseDTO has accurate values for:
    • totalPages: Matches the Page's total pages
    • totalElements: Matches the Page's total elements
    • number: Matches the 0-based page number from the Page
    • 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)
  • totalElements is set to the size of your list (2)
  • totalPages is 1 (since there's only one page of data with your list)
  • number (current page index) is 0 (since the default Pageable is 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 15:52:51