【问题标题】:Testing a private method without call in Unit Test在不调用单元测试的情况下测试私有方法
【发布时间】:2021-08-31 14:14:55
【问题描述】:

在我的 Java 应用程序中,我想测试以下公共方法:

@Override
public List<ProductDTO> findByZoneOffset(final int zoneOffset) {
    final List<String> zoneIdList = getTimeZonesByZoneOffset(zoneOffset);
   
    final List<UUID> productConfigUuidList = 
        productConfigRepository.findAllUuidByZoneIdIn(zoneIdList);
    final List<Product> products = 
        productRepository.findAllBySiteConfigUuidIn(productConfigUuidList);

    return getProductDTOList(product);
}

有一个私有方法叫做之前的公共方法:

private static List<String> getTimeZonesByZoneOffset(final int zoneOffset) {
    return ZoneId.getAvailableZoneIds()
            .stream()
            .filter(zoneId -> ZoneId.of(zoneId)
                    .getRules()
                    .getOffset(Instant.now())
                    .equals(ZoneOffset.ofHours(zoneOffset)))
            .sorted()
            .collect(Collectors.toList());
}

我创建了以下单元测试来测试findByZoneOffset() 方法。 但是,我无法评估 zoneIdList 的相同值 我可以在服务方法中 (getTimeZonesByZoneOffset) 因此 @ 987654326@ 服务中的值返回空列表

@Test
public void test_findByZoneOffset() {
    final int numRecords = 3;
    final List<Product> productList = new ArrayList<>();

    final List<String> zoneIdList = new ArrayList<>();
    zoneIdList.add("Africa/Nairobi");
    zoneIdList.add("Asia/Baghdad");
    zoneIdList.add("Europe/Moscow");

    final List<UUID> productConfigUuidList = new ArrayList<>();
    final List<ProductConfig> productConfigList = new ArrayList<>();

    for (int i = 0; i < numRecords; i++) {
        final Product product = new Product();
        final ProductConfig productConfig = new ProductConfig();
        productConfig.setZoneId(zoneIdList.get(i));
        productConfigUuidList.add(productConfig.getUuid());
        productConfigList.add(productConfig);
        product.setProductConfigUuid(productConfig.getUuid());
        productList.add(product);
    }

    when(productConfigRepository.findAllUuidByZoneIdIn(zoneIdList))
        .thenReturn(productConfigUuidList);
    when(productRepository.findAllBySiteConfigUuidIn(productConfigUuidList))
        .thenReturn(productList);
    when(productRepository.findAll(any(ProductCriteriaRequest.class)))
        .thenReturn(productList);
    when(productConfigRepository.findAllByUuidIn(anyList()))
        .thenReturn(productConfigList);

    final List<ProductDTO> productDTOList = 
        productService.findByZoneOffset(numRecords);

    for (int i = 0; i < numRecords; i++) {
        assertEquals(zoneIdList.get(i), 
            productDTOList.get(i).getConfig().getZoneId());
    }
}

那么,我应该如何在测试方法中模拟zoneIdList,并在不调用私有方法的情况下使用与服务方法中相同的值?

请注意,私有方法是static,我不确定是否可以测试它,即使我将它移到我的Util 类并使其成为public

【问题讨论】:

    标签: java spring unit-testing testing mocking


    【解决方案1】:

    您可以创建另一个受保护的方法(包或子类私有)。这个新方法除了调用私有方法之外什么都不做。

    然后你添加一个单元测试类,它驻留在同一个包中并且可以测试那个私有方法。

    在代码中,这看起来很简单

    private static List<String> getTimeZonesByZoneOffset(final int zoneOffset) {
        return ...
    }
    
    protected static List<String> getTimeZonesByZoneOffset2(final int zoneOffset) {
        return getTimeZonesByZoneOffset(zoneOffset);
    }
    

    然后为 getTimeZonesByZoneOffset2 编写单元测试。

    【讨论】:

    • 您为什么不将此作为答案发布?我的意思是,为什么不在您的答案中添加代码?这对每个人都会更有用。
    猜你喜欢
    • 2017-12-01
    • 1970-01-01
    • 2023-01-09
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多