关于Android单元测试的几个重要问题

发表于:2016-12-29 11:16

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:键盘男    来源:51Testing软件测试网采编

  3.解决内部new对象
  小白:“我在Presenter里new Model,Model依赖比较多,会做sql操作,等等.....Presenter依赖Model返回结果,导致Presenter没法单元测试啦!求大神指点!”
  小白C的例子:Model:
  Presenter:
  错误的单元测试:
  还是那句话:依赖隔离。我们隔离Model依赖,即mock Model对象,而不是new Model()。
  找找以上PresenterTest的问题吧:PresenterTest完全不知道Model的存在,意思是无法mock Model。那么,我们就想办法把mock Model传给Presenter——在Presenter构造函数传参!
  改进Presenter:
  正确的单元测试:
  事情就这么解决了。如果你觉得在Activity直接用默认Presenter构造函数,在构造函数new Model()比较方便,那就保留默认构造函数呗。当然使用dagger2就不存在多个构造函数了,都是构造传参。
  4.静态方法
  小白:“大神,我在Presenter用到静态方法....”笔者:“行了,知道你要说什么。”
  解决方法跟上面【解决内部new对象】大同小异,核心思想还是依赖隔离。
  1).把sign(...)改成非静态方法;
  2).把SignatureUtils作为成员变量;
  3).构造方法传入SignatureUtils;
  4).单元测试时,把mock SignatureUtils传给Presenter。
  改进后Presenter:
  5.RxJava异步转同步
  小白:“大神...”
  笔者:“为师掐指一算,料汝会遇此劫难。”
  小白:(传说中从入门到出家?)
  单元测试
  运行RxPresenterTest:
  你会发现没有输出"test",为什么呢?
  由于testRxJava里面,Obserable.subscribeOn(Schedulers.io())把线程切换到io线程,并且delay了1秒,而testTestRxJava()单元测试早已在当前线程跑完了。笔者试过,即使去掉delay(1, TimeUnit.SECONDS),还是不会输出‘test’。
  可以看到笔者把.observeOn(AndroidSchedulers.mainThread())注释掉了,我们把那句代码加上,再跑一下testTestRxJava(),会报java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked.:
  这是由于jdk没有android.os.Looper这个类及相关依赖。
  解决以上两个问题,我们只要把Schedulers.io()&AndroidSchedulers.mainThread()切换为Schedulers.immediate()就可以了。RxJava开发团队已经为大家想好了,提供了RxJavaHooks和RxAndroidPlugins两个hook操作的类。
  在RxPresenterTest.setUp()加一句RxTools.asyncToSync();:
  再跑一次testTestRxJava():
  总算输出"test",感谢上帝啊!(应该打赏下笔者吧^_^)
  读者有没发现RxTools.asyncToSync()多加了一句RxJavaHooks.setOnComputationScheduler(schedulerFunc),意思将computation线程切换为immediate线程。笔者发现,仅仅添加RxJavaHooks.setOnIOScheduler(schedulerFunc),对于有delay的Obserable还是未通过,于是顺手把computation线程也切换了,于是就可以了。
  还有RxJavaHooks.reset()和RxAndroidPlugins.getInstance().reset(),笔者发现,当运行大量单元测试时,有些会失败,但单独运行失败的单元测试,又通过了。百思不得其解后,添加了那两句.....可以了!
  (关于RxJavaHooks和RxAndroidPlugins的使用,在很久前的文章 《(MVP+RxJava+Retrofit)解耦+Mockito单元测试 经验分享》已经提及过)
  小结
  笔者:“小白同学,现在你踩过的坑,填好未?”
  小白:“方丈,啊不,大神,上面几个问题是解决了,不过还有其他问题。”
  笔者:“不挖坑,怎么填坑呢?以后再给你讲讲其他单元测试的玄机。”
  小白:“......”
  本文详述了几个单元测试重要问题的解决方法,读者不难发现,笔者一直强调 依赖隔离、依赖隔离、依赖隔离,这个概念在单元测试中相当重要。还搞不懂这个概念的同学,看多几次《Android单元测试 - 如何开始?》(又厚颜无耻地广告),同时在实践中不断回顾这个理念。
  只要解决好这几个问题,Presenter单元测试就不难了。还有本文未提及的sqlite、SharedPreferences单元测试、在后面的文章会给读者介绍下。
  感谢读者对笔者一直以来的支持,麻烦点赞&随手转发,好人一世平安。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号