【发布时间】:2018-03-16 16:21:10
【问题描述】:
下面的方法有 3 种可能的路径: 1. 真的, 2. 错误的, 3. 例外。
为了测试它,我需要模拟 True 和 Exception 路径的私有 getWootsWithAvailableProducts。然而,集体智慧似乎在说你不应该嘲笑私有方法。如果我不模拟私有方法并监视它以进行验证,我还能如何测试这些路径。如果这都是真的,为什么模拟私有方法这么难。如果不是真的,我错过了什么?
测试中:
public List<Woot> findAllWoots(final boolean isBuy) throws Exception {
final List<Woot> allWoots = wootService.findAllWoots();
return isBuy ? getWootsWithAvailableProducts(allWoots) : allWoots;
}
更多细节:
getWootsWithAvailableProducts 调用发出网络请求的公共服务。因此,我可以模拟实际的服务类并防止发生任何网络请求。
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.
}
【问题讨论】:
-
拨打
getWootsWithAvailableProducts有什么影响吗? -
是的,它调用了一个发出网络请求的服务。
-
这是一个外部依赖项,应该抽象出它自己的关注点,因为它与您的代码紧密耦合并且难以单独测试。
-
这意味着: 1. 你的网络服务依赖是隐藏的,不能被模拟,你的类与它不必要地耦合; 2. 你的课做的太多了; 3.(很可能)你的测试想法是不正确的,你的测试将与被测试的类紧密耦合。扩大您的测试范围并将测试编写为一个单元规范,而不是每个 if/else 分支的测试。
-
该方法中只有两个路径,而不是三个。集体智慧关于不模拟私有方法是正确的,因为它们只是实现细节。一般来说,关于自动化开发人员测试,需要了解的重要一点是他们应该测试有意义的功能,仅此而已;一个好的测试只关心验证 SUT 某些部分的“业务”特性,而不关心代码片段。如果可能的话,最好不要使用嘲笑。仅在绝对必要时使用。