Customize the default response when no handler is configured
no_handler_status_code is nice to set a 404 status instead of 500 when no handler has been defined. However it would be nice if the full default response was customizable.
I test an API where all responses must be JSON, 404 or 500 pages included. Some URLs I check are built dynamically, so it would not be very convenient to prepare pytest-httpserver for all those URLs. A customizable default response here would be a bliss.
What do you think?
hi @azmeuk ,
It depends on whether you want to make the request to cause an error (when a request arrives which has no handler registered).
In the current code it registers such a request as an error and later on if you call the check_assertions() method of the server, then it will raise AssertionError with some description.
I'm asking it because you can register a catch-all handler like this:
def test_catch_all(httpserver: HTTPServer):
httpserver.expect_request("/foo").respond_with_data("Foo")
# this should be the last handler registered
httpserver.expect_request(re.compile(".*")).respond_with_data("Catchall", status=404)
assert requests.get(httpserver.url_for("/foo")).text == "Foo"
resp = requests.get(httpserver.url_for("/some_nonexisting"))
assert resp.text == "Catchall"
assert resp.status_code == 404
httpserver.check_assertions() # this will succeed
but it won't cause check_assertions() to fail.
(If you don't like the ".*" regexp then you can also create an URIPattern object which matches all requests, no matter what they look like.)
If you want to have the check_assertions() to fail, that's a different thing.
In such case you can override the respond_nohandler method of the httpserver.
import pytest
from werkzeug import Response
from pytest_httpserver import HTTPServer
import requests
# this can go to conftest.py
class MyHttpServer(HTTPServer):
def respond_nohandler(self, request, extra_message=""):
super().respond_nohandler(request, extra_message)
return Response("My custom text", status=404)
@pytest.fixture(scope="session")
def make_httpserver():
# code is taken from make_httpserver in the original pytest-httpserver's code
# https://github.com/csernazs/pytest-httpserver/blob/master/pytest_httpserver/pytest_plugin.py#L42
server = MyHttpServer()
server.start()
yield server
server.clear()
if server.is_running():
server.stop()
## this can go to test_x.py
## your tests will receive your custom object
def test_example(httpserver: HTTPServer):
resp = requests.get(httpserver.url_for("/nonexisting"))
assert resp.text == "My custom text"
assert resp.status_code == 404
# this will fail if uncommented:
# httpserver.check_assertions()
In other words you can customize the server behavior by overriding a pytest fixture and by overriding a method in the derived class.
What do you think? Would any suggestion be useful for you?
If you don't like the 2nd option, how would the new feature look like? Like this?
def func(request: Request):
return Response(...)
def test_example(httpserver):
httpserver.register_nohandler(func)
Zsolt