python:httmock 一个生成伪造请求的库
用于Python 2.7和3.4+的请求的mocking库。
Installation
C:\Users\lifeng>pip install httmock
Collecting httmock
Downloading httmock-1.4.0-py3-none-any.whl (4.8 kB)
Requirement already satisfied: requests>=1.0.0 in d:\python\python37\lib\site-packages (from httmock) (2.25.0)
Requirement already satisfied: idna<3,>=2.5 in d:\python\python37\lib\site-packages (from requests>=1.0.0->httmock) (2.9)
Requirement already satisfied: chardet<4,>=3.0.2 in d:\python\python37\lib\site-packages (from requests>=1.0.0->httmock) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in d:\python\python37\lib\site-packages (from requests>=1.0.0->httmock) (2020.4.5.1)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in d:\python\python37\lib\site-packages (from requests>=1.0.0->httmock) (1.26.2)
Installing collected packages: httmock
Successfully installed httmock-1.4.0
基础使用
在内部可以用它来模拟请求第三方api和测试库,有条件地使用带有urlmatch装饰器的模拟应答:
from httmock import urlmatch, HTTMock
import requests
@urlmatch(netloc='baidu.com')
def baidu_mock(url, request):
return 'Testing response'
with HTTMock(baidu_mock):
r = requests.get('https://baidu.com/')
print (r.content)
运行结果:
F:\project_gitee\Test\pythonScripts>D:/Python/Python37/python.exe f:/project_gitee/Test/pythonScripts/pythonLibrary/pythonModule2.py
b'Testing response'
如果你请求的地址跟你定义的条件不符合,就不会抛出你预期要返回的值:
from httmock import urlmatch, HTTMock
import requests
@urlmatch(scheme='http', netloc='baidu.com', path='/index', method="GET", query="type=1")
def baidu_mock(url, request):
return 'Testing response'
with HTTMock(baidu_mock):
r = requests.get('https://baidu.com/index?type=1')
print (r.content)
运行结果:
F:\project_gitee\Test\pythonScripts>D:/Python/Python37/python.exe f:/project_gitee/Test/pythonScripts/pythonLibrary/pythonModule2.py
b'<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\n<html><head>\n<title>404 Not Found</title>\n</head><body>\n<h1>Not Found</h1>\n<p>The requested URL /index was not found on this server.</p>\n</body></html>\n'
重要知识点:
定义的条件:scheme='http', netloc='baidu.com', path='/index', method="GET", query="type=1"
必须要和请求的路径一致:requests.get('http://baidu.com/index?type=1')
或者你可以直接使用这种正则匹配的方式,它相当于万能匹配:
from httmock import urlmatch, HTTMock
import requests
@urlmatch(netloc=r'(.*\.)?baidu\.com$')
def baidu_mock(url, request):
return 'Testing response'
with HTTMock(baidu_mock):
r = requests.get('http://baidu.com/index?type=1')
print (r.content)
运行结果:
F:\project_gitee\Test\pythonScripts>D:/Python/Python37/python.exe f:/project_gitee/Test/pythonScripts/pythonLibrary/pythonModule2.py
b'Testing response'
进阶使用
上文说了用正则处理,httmock
库提供了all_requests
装饰器,它不会有条件地阻止真实请求。如果返回一个字典,它将映射到requests.Response
对象返回:
from httmock import all_requests, HTTMock
import requests
@all_requests
def response_content(url, request):
return {'status_code': 200,
'content': 'hello world'}
with HTTMock(response_content):
r = requests.get('https://api_data')
print(r.status_code)
print(r.content)
运行结果:
F:\project_gitee\Test\pythonScripts>D:/Python/Python37/python.exe f:/project_gitee/Test/pythonScripts/pythonLibrary/pythonModule2.py
200
b'hello world'
上述代码中,清晰看到没有定义接口路径,可以随意输入一个乱七八糟的api进行请求。
如果传入Set-Cookie
头,request.Response.cookies
将包含这些值。你也可以直接使用response
方法而不是直接返回一个字典:
from httmock import all_requests, response, HTTMock
import requests
@all_requests
def response_content(url, request):
headers = {'content-type': 'application/json',
'Set-Cookie': 'foo=bar;'}
content = {'message': 'hello world'}
return response(403, content, headers, None, 5, request)
with HTTMock(response_content):
r = requests.get('https://www.baidu.com')
print(r.json())
print(r.cookies)
print(r.cookies['foo'])
print(r.json().get('message'))
运行结果:
F:\project_gitee\Test\pythonScripts>D:/Python/Python37/python.exe f:/project_gitee/Test/pythonScripts/pythonLibrary/pythonModule2.py
{'message': 'hello world'}
<RequestsCookieJar[<Cookie foo=bar for www.baidu.com/>]>
bar
hello world
以上总结或许能帮助到你,或许帮助不到你,但还是希望能帮助到你,如有疑问、歧义,直接私信留言会及时修正发布;非常期待你的点赞和分享哟,谢谢!
未完,待续…
一直都在努力,希望您也是!
微信搜索公众号:就用python