使用 Android 官方工具类 TextUtils 的测试问题

Android 虽然提供了很方便的工具类方法,但是实际上究竟要不要使用,如何使用却并不是那么简单的事情。

TextUtils 是 Android 官方提供的文本处理工具类,类全面 android.text.TextUtils,从 API 等级 1 的时候就可以使用。毕竟 Java 本身的 String 类的功能比较单薄,无法应对很多常见的应用场景。这个工具类中有很多很有用的方法,个人常用的方法有:

返回值方法名描述
booleanequals(CharSequence a, CharSequence b)判断两个字符串是否相等,可处理参数为 null 的情况
booleanisDigitsOnly(CharSequence str)判断字符串是否只包含数字
booleanisEmpty(CharSequence str)判断字符串是否为 null 或者长度为 0
Stringjoin(CharSquence delimiter, Object[] tokens)把 tokens 参数使用 delimiter 组合后返回结果字符串

这些工具方法自己写比较耗时,有时还会遗漏特殊应用常见的边界检查,所以我一开始总是在需要它的地方直接使用,省了很多自己写工具类的时间。

TextUtils 以及类似的 Android 工具类确实对编程帮助很大,而且大多不用考虑兼容的 API 等级,也不用导入额外的依赖。可惜,这些工具类并不完美,它方便的原因和造成困扰的原因是相同的 —— 它是 Android 框架提供的代码。这就意味着在需要写本地单元测试的场景使用它会给测试造成很多麻烦,比如:MVP 模式中的 Presenter 层代码,另外 Model 层代码虽然常常和 Android 框架发生交互,但有些子模块(如:获取网络数据)也是最好不要和 Android 框架发生纠缠的。 当然,真的使用了也不是没法进行测试,只是会在测试的时候写一些很琐碎的 PowerMock 代码设置。但是,我们必须要知道单元测试中这样繁琐的进行 Mock 操作一方面降低了测试的效率,另一方面会造成无用信息的过度膨胀。此外,它会造成我们无法实现真正的黑盒单元测试,毕竟要高度依赖代码的具体实现方式。

其实,解决方案也很简单,就是在它造成麻烦的地方使用自己写的工具方法作替代,但在其他场景(如:数据库操作类)仍旧可以使用原有的代码。 实际上,MVP 等模式一大应用目的就是为了尽量分离出 Android 框架无关的管理代码,方便迭代和测试,不能因为一点点的小方便而给架构增添问题。写代码还是要有整体的架构层面的思考,分清主次,知道取舍。 当然,如果函数能使第一类公民的话,说不定工具类的 Mock 操作就不会这么麻烦了。