-
Hey there, I'm struggeling with setting up some test cases for my falcon app and can't quite make it work. Here my very simplified example server: import json
import falcon
class Index:
def on_post(self, req, rsp):
content = json.load(req.stream)
rsp.text = f"You got this: {str(json.dumps(content))}"
rsp.content_type = "application/json"
rsp.status = falcon.HTTP_200
def create():
APP = falcon.App()
APP.add_route("/", Index())
return APP This works fine. I run this with a cheroot wsgi server and get the expected response (all running in a container). Now I'm trying to setup a test case using import pytest
import app.falcon as fl
from falcon import testing
@pytest.fixture
def client():
return testing.TestClient(fl.create())
def test_index(client):
response = client.simulate_post("/", json={"hurr": "durr"})
assert response.status_code == 200
assert response.text == 'You got this: {"hurr": "durr"}' This leads to the following error: ==================================================================================== test session starts =====================================================================================
platform linux -- Python 3.9.6, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /data
plugins: cov-2.10.1, asyncio-0.15.1, requests-mock-1.8.0, subprocess-1.0.1, mock-3.3.1
collected 1 item
tests/test_falcon.py F [100%]Coverage.py warning: Module connaisseur was never imported. (module-not-imported)
Coverage.py warning: No data was collected. (no-data-collected)
WARNING: Failed to generate report: No data to report.
/usr/local/lib/python3.9/site-packages/pytest_cov/plugin.py:271: PytestWarning: Failed to generate report: No data to report.
self.cov_controller.finish()
========================================================================================== FAILURES ==========================================================================================
_________________________________________________________________________________________ test_index _________________________________________________________________________________________
client = <falcon.testing.client.TestClient object at 0x7f97e001a850>
def test_index(client):
response = client.simulate_post("/", json={"hurr": "durr"})
> assert response.status_code == 200
E assert 500 == 200
E + where 500 = <falcon.testing.client.Result object at 0x7f97e001af70>.status_code
tests/test_falcon.py:13: AssertionError
------------------------------------------------------------------------------------ Captured stderr call ------------------------------------------------------------------------------------
2021-10-12 15:47:45 [FALCON] [ERROR] POST / => Traceback (most recent call last):
File "falcon/app.py", line 361, in falcon.app.App.__call__
File "/usr/local/lib/python3.9/site-packages/app/falcon.py", line 6, in on_post
content = json.load(req.stream)
File "/usr/local/lib/python3.9/json/__init__.py", line 293, in load
return loads(fp.read(),
File "/usr/local/lib/python3.9/wsgiref/validate.py", line 197, in read
assert_(len(args) == 1)
File "/usr/local/lib/python3.9/wsgiref/validate.py", line 128, in assert_
raise AssertionError(*args)
AssertionError
----------- coverage: platform linux, python 3.9.6-final-0 -----------
================================================================================== short test summary info ===================================================================================
FAILED tests/test_falcon.py::test_index - assert 500 == 200
===================================================================================== 1 failed in 0.18s ====================================================================================== Obvious question now ... what am I doing wrong? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi @phbelitz! In order to make your code work on any PEP-3333 compliant WSGI server regardless of the underlying implementation, you can instead use our The following passes for me: import json
import falcon
import pytest
from falcon import testing
class Index:
def on_post(self, req, rsp):
content = json.load(req.bounded_stream)
rsp.text = f"You got this: {str(json.dumps(content))}"
rsp.content_type = "application/json"
rsp.status = falcon.HTTP_200
def create():
APP = falcon.App()
APP.add_route("/", Index())
return APP
@pytest.fixture
def client():
return testing.TestClient(create())
def test_index(client):
response = client.simulate_post("/", json={"hurr": "durr"})
assert response.status_code == 200
assert response.text == 'You got this: {"hurr": "durr"}'
P.S. You might also check our Internet media handling features to reduce the amount of manual wrangling of serialization and deserialization. import json
import falcon
import pytest
from falcon import testing
class Index:
def on_post(self, req, resp):
content = req.get_media()
resp.media = {'info': f"You got this: {json.dumps(content)}"}
def create():
app = falcon.App()
app.add_route("/", Index())
return app
@pytest.fixture
def client():
return testing.TestClient(create())
def test_index(client):
response = client.simulate_post("/", json={"hurr": "durr"})
assert response.status_code == 200
assert response.json == {'info': 'You got this: {"hurr": "durr"}'} |
Beta Was this translation helpful? Give feedback.
Hi @phbelitz!
In order to simulate requests without going over the network, Falcon's test client uses
wsgiref
's machinery, which has some glitches in its input stream wrapper (you might observe a similar behavior usingwsgiref.simple_server
). This is discussed more in depth here:req.stream
. See also: Why does req.stream.read() hang for certain requests?In order to make your code work on any PEP-3333 compliant WSGI server regardless of the underlying implementation, you can instead use our
req.bounded_stream
wrapper, which works around the most common differences in WSGI input stream behavior.The following passes for me: