更喜欢通过详细的实现类来测试公共API

来源:互联网 发布:淘宝网上怎么进货 编辑:程序博客网 时间:2024/04/20 10:38

作者: Andrew Trenk

原文链接:http://googletesting.blogspot.tw/2015/01/testing-on-toilet-prefer-testing-public.html

这个类需要测试吗?

class UserInfoValidator {

   public void validate(UserInfo info){

if (info.getDateOfBirth().isInFuture()) { throw new ValidationException());}

  }                        

}

它的方法有一些逻辑,所以对其进行测试可能是个好主意。但是如果它的用户是唯一的呢?

public class UserInfoService {

     private UserInfoValidatorvalidator;

public void save(UserInfo info) {

validator.validate(info); // Throw an exception if the value is invalid.

writeToDatabase(info);  

  }

}

答案是:也许不需要对其进行测试,因为所有的路径可以通过UserInfoService被测试到。主要的区别在于这个类是一个详细的实现父类,而不是一个公共API。

一个公共API可以被任意数量的用户访问,用户可以输入任何的组合传递给它的方法。你要确保这些测试,即确保用户使用这些API时不会看到问题。一个关于公共API的例子,公共API被代码库中不同的类调用(例如:一个服务器端的类被客户端使用)和常见的被使用于整个代码库的工具类。

一个详细的实现类的存在仅仅为了支持公共API并且被非常有限的用户使用(往往是只有一个用户)。这些类有时可以通过使用它们的公共API被间接测试。

测试实现详细的类在很多case中仍然是有用的,比如这个类是复杂的,或者如果这个测试很难写公共API类。当你对它们进行测试时,它们经常不需要测试的像公共API一样深入,因为一些输入可能永远不会被传递到他们的方法中。(上面的代码示例中,如果UserInfoService可以保证UserInfo永远不为null,那么null将不会被当做UserInfoValidator.validate的参数传入,因为它永远不会发生。)

详细的实现类有时被认为是发生在一个单独的类中的私有方法,因为你通常也不想直接测试私有方法。你也可以试着约束实现类的能见度,例如让他们的包私有在java中。
实现测试细节的类会导致一些问题:

-如果你需要经常更新测试,比如改变一个实现细节类的方法签名或者甚至是重构时,代码很难维护。如果只是公共API的测试,就不会存在这个问题。

- 如果你测试一个行为仅通过细节的实现类,你可能会对你的代码有错误的自信,因为相同的代码路径在公共的API下可能无法正常工作。在重构时也要多加小心,如果不是所有的路径都通过公共API测试,它可能难以确保公共API的所有行为。

0 0