@Override
    public Page<ConfigHistoryInfo> findConfigHistory(String dataId, String group, String tenant, int pageNo,
            int pageSize) {
        PaginationHelper<ConfigHistoryInfo> helper = createPaginationHelper();
        String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant;
        
        MapperContext context = new MapperContext((pageNo - 1) * pageSize, pageSize);
        context.putWhereParameter(FieldConstant.DATA_ID, dataId);
        context.putWhereParameter(FieldConstant.GROUP_ID, group);
        context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp);
        
        HistoryConfigInfoMapper historyConfigInfoMapper = mapperManager.findMapper(
                dataSourceService.getDataSourceType(), TableConstant.HIS_CONFIG_INFO);
        
        String sqlCountRows = historyConfigInfoMapper.count(Arrays.asList("data_id", "group_id", "tenant_id"));
        MapperResult sqlFetchRows = historyConfigInfoMapper.pageFindConfigHistoryFetchRows(context);
        
        Page<ConfigHistoryInfo> page;
        try {
            page = helper.fetchPage(sqlCountRows, sqlFetchRows.getSql(), sqlFetchRows.getParamList().toArray(), pageNo,
                    pageSize, HISTORY_LIST_ROW_MAPPER);
        } catch (DataAccessException e) {
            LogUtil.FATAL_LOG.error("[list-config-history] error, dataId:{}, group:{}", new Object[] {dataId, group},
                    e);
            throw e;
        }
        return page;
    }
@Test
    void testFindConfigHistory() {
        String dataId = "dataId34567";
        String group = "group34567";
        String tenant = "tenant34567";
        
        //mock count
        Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), eq(Integer.class))).thenReturn(300);
        //mock list
        List<ConfigHistoryInfo> mockList = new ArrayList<>();
        mockList.add(createMockConfigHistoryInfo(0));
        mockList.add(createMockConfigHistoryInfo(1));
        mockList.add(createMockConfigHistoryInfo(2));
        Mockito.when(jdbcTemplate.query(anyString(), eq(new Object[] {dataId, group, tenant}), eq(HISTORY_LIST_ROW_MAPPER)))
                .thenReturn(mockList);
        int pageSize = 100;
        int pageNo = 2;
        //execute & verify
        Page<ConfigHistoryInfo> historyReturn = externalHistoryConfigInfoPersistService.findConfigHistory(dataId, group, tenant, pageNo,
                pageSize);
        assertEquals(mockList, historyReturn.getPageItems());
        assertEquals(300, historyReturn.getTotalCount());
        
        //mock exception
        Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), eq(Integer.class)))
                .thenThrow(new CannotGetJdbcConnectionException("conn error111"));
        try {
            externalHistoryConfigInfoPersistService.findConfigHistory(dataId, group, tenant, pageNo, pageSize);
            assertTrue(false);
        } catch (Exception e) {
            assertEquals("conn error111", e.getMessage());
        }
    }