我正在编写一个 REST 客户端,我需要在测试中模拟 HTTP 服务器。最适合做到这一点的图书馆是什么?如果我可以创建预期的 HTTP 请求并将其与实际进行比较,那就太好了。
尝试HTTPretty,Python 的 HTTP 客户端模拟库可帮助您专注于客户端。
您还可以自己创建一个小型模拟服务器。 我正在使用一个名为 Flask 的小型网络服务器。
import flask
app = flask.Flask(__name__)
def callback():
return flask.jsonify(list())
app.add_url_rule("users", view_func=callback)
app.run()
这将在 http://localhost:5000/users 下生成一个服务器,并执行回调函数。
我创建了一个要点来提供带有关闭机制等的工作示例。 https://gist.github.com/eruvanos/f6f62edb368a20aaa880e12976620db8
您无需使用任何外部库,只需运行临时 HTTP 服务器即可完成此操作。
例如模拟 https://api.ipify.org?format=json
"""Unit tests for ipify"""
import http.server
import threading
import unittest
import urllib.request
class MockIpifyHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
"""HTTPServer mock request handler"""
def do_GET(self): # pylint: disable=invalid-name
"""Handle GET requests"""
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(b'{"ip":"1.2.3.45"}')
def log_request(self, code=None, size=None):
"""Don't log anything"""
class UnitTests(unittest.TestCase):
"""Unit tests for urlopen"""
def test_urlopen(self):
"""Test urlopen ipify"""
server = http.server.ThreadingHTTPServer(
("127.0.0.127", 9999), MockIpifyHTTPRequestHandler
)
with server:
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
request = request = urllib.request.Request("http://127.0.0.127:9999/")
with urllib.request.urlopen(request) as response:
result = response.read()
server.shutdown()
self.assertEqual(result, b'{"ip":"1.2.3.45"}')
我找到的替代解决方案位于https://stackoverflow.com/a/34929900/15862
Mockintosh 似乎是另一种选择。
您可以信赖pytest-httpserver。
它当场启动一个服务器 - localhost,该服务器在拆卸时关闭。
# the httpserver is a fixture automatically provided by the library
async def test_get_location(httpserver: HTTPServer):
# setup the expected calls to the server
httpserver.expect_oneshot_request(
method="GET",
uri="/locations/location_123",
)
# now you can call httpserver.url_for("/locations/location_123") with any HTTP client
# IRL you'd inject the base URL (httpserver.url_for("") in your component under test;
# then you'd call the method under test which would consume the setup calls
超快、干净、真实,并且不涉及任何模拟。