JMockit - 验证私有方法

JMockit - verify private method

下面的方法有 3 个可能的路径: 1. 没错, 2. 错误, 3.异常。

为了测试它,我需要为 TrueException 路径模拟私有 getWootsWithAvailableProducts。然而,集体智慧似乎在说你不应该嘲笑私有方法。如果我不模拟私有方法并监视它以进行验证,我还能如何测试这些路径。如果这一切都是真的,为什么模拟私有方法如此困难。如果不是真的,我错过了什么?

正在测试中:

  public List<Woot> findAllWoots(final boolean isBuy) throws Exception {

    final List<Woot> allWoots = wootService.findAllWoots();

    return isBuy ? getWootsWithAvailableProducts(allWoots) : allWoots;
  }

更多详情:

getWootsWithAvailableProducts 调用发出网络请求的 public 服务。因此,我可以模拟实际服务 class 并防止发生任何网络请求。

private List<Woot> getWootsWithAvailableProducts(List<Woot> allWoots)
    throws ServiceException {

    final String stringOfWootIds = buildStringOfCommaSeparatedIDs(allWoots);
    final List<Count> categoryIDs = wootSearchService
        .getWootIDsOfAvailableProducts(stringOfWootIds);

    return filterOnlyWootsWithAvailProducts(allCategories, categoryIDs);// also private.
}

您可以为调用此私有方法的可访问方法编写测试,然后测试所有可能的结果

此外,请确保您正在模拟其他 class 函数和所有变量,否则在测试时执行私有函数时可能会导致问题。

基本上,您将测试如下可能的场景:

Public函数当私有函数returns

  1. 正确
  2. 错误
  3. 异常

希望对您有所帮助。

根据评论表明 getWootsWithAvailableProducts

calls a service that makes a network request

这是一个外部依赖项,应该将其抽象出来并纳入其自身的关注点,因为它与您的代码紧密耦合并且难以单独测试。

public interface WootProductsService {
    List<Woot> getWootsWithAvailableProducts(List<Woot> woots);
}

所述抽象的实现将封装网络调用,解耦原始代码,以便在单独测试方法时可以模拟抽象。

WootProductsService wootProductService; //Injected

public List<Woot> findAllWoots(final boolean isBuy) throws Exception {

    final List<Woot> allWoots = wootService.findAllWoots();

    return isBuy ? wootProductService.getWootsWithAvailableProducts(allWoots) : allWoots;
}

您现在可以控制所有依赖项,并可以在测试所有场景时根据需要操作它们。

注意您的方法和 classes 的问题,因为它们会表明您的 class 是否做得太多。

如果在测试代码时遇到问题,请将其视为设计有问题的标志。查看问题的原因并考虑需要应用哪些重构以使代码更可靠。