python mock测试的示例
mock总所周知是模拟的意思,我们在做接口测试的时候有时候会发现部分功能依赖其他业务场景或者第三方功能或者是线上数据或者业务场景过于复杂(需要大量调用)的情况,没有办法通过接口调用或者做断言,这个时候就需要mock了
python2中需要pipinstallmock来导入mock第三方模块,而python3中被引入到unittest框架中,直接fromunittestimportmock就可以导入mock模块了
在单元测试中只针对当前单元做测试,就是测试当前方法或者是当前类,但是如果出现这个方法依赖其他第三方模块,那不是还要校验其他方法了吗,那就违背了单元测试这个概念了,所有将外部依赖组件实现模拟并替换掉,使得单元测试的焦点放在自己身上
为了演示,用fastapi模拟了一个tx和ali的接口来调用作为单元测试,可以看到需要同时调用两个接口才能完成单元测试
fromunittestimportTestCase,main,mock importrequests classRequest(object): defrequest_tx(self): tx_url='http://127.0.0.1:8000/tx' tx_data={"a":1,"b":2} tx_result=requests.post(tx_url,json=tx_data) tx_result=tx_result.json() returntx_result defrequest_ali(self): ali_url='http://127.0.0.1:8000/ali' ali_data={"c":1,"d":2} ali_result=requests.post(ali_url,json=ali_data) ali_result=ali_result.json() returnali_result classMyproject(TestCase): deftest_api(self): r=Request() ali_result=r.request_ali() tx_result=r.request_tx() self.assertEqual(int(ali_result['result']['all_add_value'])+int(tx_result['result']['all_add_value']),6)
''' @File:mock_third_server.py @Copyright:rainbol @Date:2020/9/28 @Desc: ''' fromfastapiimportFastAPI frompydanticimportBaseModel importuvicorn app=FastAPI() defadd(a,b): returna+b #json参数传参 classTX(BaseModel): a:int b:int @app.post('/tx') deftxApi(u:TX): u.a+=1 u.b-=1 add_result=add(u.a,u.b) return{'status':1,'result':{'value_a':u.a,'value_b':u.b,'all_add_value':add_result}} classAl(BaseModel): c:int d:int @app.post('/ali') defaliApi(u:Al): u.c*=1 u.d/=1 add_result=add(u.c,u.d) return{'status':1,'result':{'value_c':u.c,'value_d':u.d,'all_add_value':add_result}} if__name__=='__main__':#一定要加上这句话才行 uvicorn.run('mock_third_server:app',port=8000,debug=True)
可以看到上面的接口是可以调通的如果txapi因为一些原因不能返回,ali的接口是通的,如果要实现ali接口的测试就需要使用mock来模拟tx的接口了
mock方法一:(对于同一文件下/不同文件下的方法或者类进行mock)
''' @File:mock_third_server.py @Copyright:rainbol @Date:2020/9/28 @Desc: ''' fromfastapiimportFastAPI frompydanticimportBaseModel importuvicorn app=FastAPI() defadd(a,b): returna+b #json参数传参 classTX(BaseModel): a:int b:int @app.post('/tx') deftxApi(u:TX): u.a+=1 u.b-=1 add_result=add(u.a,u.b) raise("接口异常")#在这里加了异常 return{'status':1,'result':{'value_a':u.a,'value_b':u.b,'all_add_value':add_result}} classAl(BaseModel): c:int d:int @app.post('/ali') defaliApi(u:Al): u.c*=1 u.d/=1 add_result=add(u.c,u.d) return{'status':1,'result':{'value_c':u.c,'value_d':u.d,'all_add_value':add_result}} if__name__=='__main__':#一定要加上这句话才行 uvicorn.run('mock_third_server:app',port=8000,debug=True)
''' @File:local_project_mock_test.py @Copyright:rainbol @Date:2020/9/28 @Desc: ''' fromunittestimportTestCase,main,mock importrequests classRequest(object): defrequest_tx(self): tx_url='http://127.0.0.1:8000/tx' tx_data={"a":1,"b":2} tx_result=requests.post(tx_url,json=tx_data) tx_result=tx_result.json() returntx_result defrequest_ali(self): ali_url='http://127.0.0.1:8000/ali' ali_data={"c":1,"d":2} ali_result=requests.post(ali_url,json=ali_data) ali_result=ali_result.json() returnali_result classMyproject(TestCase): deftest_api(self): r=Request() ali_result=r.request_ali() tx_mock=mock.Mock( return_value={"status":1,"result":{"value_a":2,"value_b":1,"all_add_value":3}}) r.request_tx=tx_mock tx_result=r.request_tx() self.assertEqual(int(ali_result['result']['all_add_value'])+int(tx_result['result']['all_add_value']),6) if__name__=='__main__': main()
#以上将request_tx方法mock掉,可以mock掉写在同一文件的方法
mock方法二:@patch(对于不同文件下的类进行mock)
''' @File:local_project_mock_test.py @Copyright:rainbol @Date:2020/9/28 @Desc: ''' fromunittestimportTestCase,main fromunittest.mockimportpatch importmock_request_server classMyproject(TestCase): @patch("mock_request_server.Request.request_tx")#@patch装饰器模拟类对象 deftest_api(self,_mock_tx): _mock_tx.return_value={'status':1,'result':{'value_a':2,'value_b':1,'all_add_value':3}} r=mock_request_server.Request() ali_result=r.request_ali() tx_result=r.request_tx() print(tx_result) self.assertEqual(int(ali_result['result']['all_add_value'])+int(tx_result['result']['all_add_value']),6) if__name__=='__main__': main()
''' @File:mock_request_server.py @Copyright:rainbol @Date:2020/9/28 @Desc: ''' importrequests classRequest: defrequest_tx(self): tx_url='http://127.0.0.1:8000/tx' tx_data={"a":1,"b":2} tx_result=requests.post(tx_url,json=tx_data) tx_result=tx_result.json() raise('接口异常') returntx_result defrequest_ali(self): ali_url='http://127.0.0.1:8000/ali' ali_data={"c":1,"d":2} ali_result=requests.post(ali_url,json=ali_data) ali_result=ali_result.json() returnali_result
''' @File:mock_third_server.py @Copyright:rainbol @Date:2020/9/28 @Desc: ''' fromfastapiimportFastAPI frompydanticimportBaseModel importuvicorn app=FastAPI() defadd(a,b): returna+b #json参数传参 classTX(BaseModel): a:int b:int @app.post('/tx') deftxApi(u:TX): u.a+=1 u.b-=1 add_result=add(u.a,u.b) return{'status':1,'result':{'value_a':u.a,'value_b':u.b,'all_add_value':add_result}} classAl(BaseModel): c:int d:int @app.post('/ali') defaliApi(u:Al): u.c*=1 u.d/=1 add_result=add(u.c,u.d) return{'status':1,'result':{'value_c':u.c,'value_d':u.d,'all_add_value':add_result}} if__name__=='__main__':#一定要加上这句话才行 uvicorn.run('mock_third_server:app',port=8000,debug=True)
以上就是pythonmock测试的示例的详细内容,更多关于pythonmock测试的资料请关注毛票票其它相关文章!