摘要:解决这些问题并且练习这些调用的一个绝妙方法是,使用一个很好的一个测试双库通用程序。当服务器做出响应时,会使用响应数据执行回调方法。目前为止,的威力真的很赞。
测试与API交互的HTTP调用是一件令人生厌的复杂事情。测试一个真实的Web服务器时,一大堆问题随之产生:脆性测试(brittle test,因为网络或API本身的问题而导致的测试失败)、速度减慢测试(slow test,每一次HTTP调用都要花费好几秒)和不完全测试(“如何触发一个速率限制越界用例?想一想,我只希望速率限制会起作用……”)。
像Android这样的平台HTTP理应是异步调用,问题会变得更加复杂。如果在这些测试组合中添加计时器,那么你就准备好在测试API调用上认输吧。
解决这些问题并且练习这些HTTP调用的一个绝妙方法是,使用一个很好的Mockito(一个Java测试双库 double library)通用程序:ArgumentCaptor。
ArgumentCaptor与混合测试双有几分相似;有点类似存根(stub),也有点类似侦听程序(spy),但不完全是其中任何一个。可以使用参数捕获器捕获并存储传给mock/stub的参数。然而这里真正的亮点是对捕获的参数进行方法调用,对于像Retrofit回调有很大帮助。
译注:Retrofit是一个Android & Java的类型安全REST客户端。
有了Retrofit,我们可以发起一个API调用并提供一个回调方法。当服务器做出响应时,Mockito会使用响应数据执行回调方法。
下面这些代码使用Github API查询用户代码仓库:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
getApi().repositories( |
这里有三个我们想要测试的用例:理想路径(happy path,获取一些代码仓库并把传递给适配器)、错误路径(error path,向用户提示服务器错误)、特殊用例(special case, 向用户提示没有代码仓库错误)。
如果你的测试依赖于在真实的API服务器,那么第二和第三个用例会很复杂。我了解到最近GitHub有一些DDOS问题,但你肯定不能依赖它们来测试你的错误用例!
然而我们可以通过ArgumentCaptor捕获回调参数,进而完全控制发送的数据。
看一下对理想路径的测试(我用的是Robolectri,建议你也尝试一下):
1 2 3 4 5 6 7 8 9 |
Mockito.verify(mockApi).repositories(Mockito.anyString(), cb.capture());
|
captor(cb)捕获到回调,调用getValue()方法以后,通过success方法向它传递一些伪对象(dummy object)。
你可能会感叹“啊哈(原来可以这么简单)”。呵呵,如果没有也没关系。接下来可以看一下对错误路径的测试:
1 2 3 4 5 |
Mockito.verify(mockApi).repositories(Mockito.anyString(), cb.capture());
|
像之前一样,我们捕获了回调。但是这一次我们调用了failure方法,它模拟了一个API错误。如果我们需要更有针对性的错误处理(例如:如果返回状态是401,就重定向再登陆;如果是500, 弹出一条普通的系统错误消息),可以通过创建合适RetrofitError对象作为failure调用的参数。
目前为止,ArgumentCaptor的威力真的很赞。我们完全控制了捕获到的对象,并且能够给这些对象设置任意的数据或者触发任意想要测试的错误。
为了让内容更加丰富,下面是对一个特殊用例的测试:
1 2 3 4 5 6 7 8 |
Mockito.verify(mockApi).repositories(Mockito.anyString(), cb.capture());
|
(你可以在GitHub上找到示例的全部源码和工程文件)。
有一个特殊细节要注意:如果在声明捕获器时使用了Mockito注解,
1 2 |
@Captor
|
请确保在设置中的某个地方添加了下面代码:
1 |
MockitoAnnotations.initMocks( |
这种测试方法完全符合书中提到的所有特点:快速、健壮、易于使用。我们还可以通过它很容易地测试项目中很少出现的边缘情况(会话超时、服务器维护、特殊值),确保我们的应用正常运行。
虽然本文示例是专门针对某种栈(Android、Robolectric、Retrofit、Mockito),但是类似的方法几乎适用于任何应用。
祝测试愉快!
原文 Reliable API testing for Android with Retrofit and Mockito
翻译 Peter Pan
via www.importnew
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/8680.html
摘要:写单元测试时,应该把这些依赖隔离,让每个单元保持独立。以上的各种原因,都会影响单元测试的结果。在单元测试的基础上,将相关模块组合成为子系统或系统进行测试,称为集成测试。可以看到,单元测试速度比集成测试,也叫测试要快,并且开发成本也是最低。 showImg(/img/remote/1460000006811144); 原文链接:http://www.jianshu.com/p/bc996...
摘要:写在前面因个人能力有限,可能会出现理解错误的地方,欢迎指正和交流关于单元测试通常一个优秀的开源框架,一般都会有很完善的单元测试。 写在前面 因个人能力有限,可能会出现理解错误的地方,欢迎指正和交流! 关于单元测试 通常一个优秀的开源框架,一般都会有很完善的单元测试。 举个例子: showImg(/img/remote/1460000006767410); 不好意思,我调皮了 :) R...
阅读 1715·2021-10-18 13:30
阅读 2568·2021-10-09 10:02
阅读 2940·2021-09-28 09:35
阅读 2074·2019-08-26 13:39
阅读 3506·2019-08-26 13:36
阅读 1936·2019-08-26 11:46
阅读 1090·2019-08-23 14:56
阅读 1674·2019-08-23 10:38