FastApi-Testclient嘲笑功能时递归eRROR
我想使用python 3.8
测试与两个Fastapis的相互作用。在运行代码中,一个API(main_app
)通过函数connect_to_to_helper_app
调用另一个API(Helper_app
)。要在不设置两个服务器的情况下进行测试,我想使用fastapi.testclient.testclient
。不幸的是,我得到了recursionError
。
要重现错误,您需要以下文件:
# Content of minimal_example/apps.py
from fastapi import FastAPI
main_app = FastAPI()
helper_app = FastAPI()
def connect_to_helper_app():
"""
This function will be mocked in the test. In the real code, a request to the other app would be made
"""
raise NotImplemented
@main_app.get("/call_helper")
def call_helper() -> dict:
return connect_to_helper_app()
@helper_app.get("/")
def root() -> dict:
return {"msg": "This is the helper app."}
以及以下测试文件:
# Content of minimal_example/test.py
from fastapi.testclient import TestClient
from minimal_example.apps import main_app, helper_app
helper_test_client = TestClient(helper_app)
main_test_client = TestClient(main_app)
def test(mocker):
def connect_to_helper_app_with_test_client():
result = helper_test_client.get('/')
return result
mocker.patch('minimal_example.apps.connect_to_helper_app', new=connect_to_helper_app_with_test_client)
main_test_client.get('/call_helper')
我收到的错误消息是:
test.py:7 (test)
mocker = <pytest_mock.plugin.MockerFixture object at 0x0000015DFFB93F40>
def test(mocker):
def connect_to_helper_app_with_test_client():
result = helper_test_client.get('/')
return result
mocker.patch('minimal_example.apps.connect_to_helper_app', new=connect_to_helper_app_with_test_client)
> main_test_client.get('/call_helper')
test.py:14:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\.venv\lib\site-packages\requests\sessions.py:542: in get
return self.request('GET', url, **kwargs)
..\..\.venv\lib\site-packages\starlette\testclient.py:415: in request
return super().request(
..\..\.venv\lib\site-packages\requests\sessions.py:529: in request
resp = self.send(prep, **send_kwargs)
..\..\.venv\lib\site-packages\requests\sessions.py:645: in send
r = adapter.send(request, **kwargs)
..\..\.venv\lib\site-packages\starlette\testclient.py:243: in send
raise exc from None
..\..\.venv\lib\site-packages\starlette\testclient.py:240: in send
loop.run_until_complete(self.app(scope, receive, send))
C:\Users\d91802\AppData\Local\Programs\Python\Python38\lib\asyncio\base_events.py:616: in run_until_complete
return future.result()
..\..\.venv\lib\site-packages\fastapi\applications.py:208: in __call__
await super().__call__(scope, receive, send)
..\..\.venv\lib\site-packages\starlette\applications.py:112: in __call__
await self.middleware_stack(scope, receive, send)
..\..\.venv\lib\site-packages\starlette\middleware\errors.py:181: in __call__
raise exc from None
..\..\.venv\lib\site-packages\starlette\middleware\errors.py:159: in __call__
await self.app(scope, receive, _send)
..\..\.venv\lib\site-packages\starlette\exceptions.py:82: in __call__
raise exc from None
..\..\.venv\lib\site-packages\starlette\exceptions.py:71: in __call__
await self.app(scope, receive, sender)
..\..\.venv\lib\site-packages\starlette\routing.py:580: in __call__
await route.handle(scope, receive, send)
..\..\.venv\lib\site-packages\starlette\routing.py:241: in handle
await self.app(scope, receive, send)
..\..\.venv\lib\site-packages\starlette\routing.py:52: in app
response = await func(request)
..\..\.venv\lib\site-packages\fastapi\routing.py:234: in app
response_data = await serialize_response(
..\..\.venv\lib\site-packages\fastapi\routing.py:148: in serialize_response
return jsonable_encoder(response_content)
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:107: in jsonable_encoder
jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
E RecursionError: maximum recursion depth exceeded in comparison
!!! Recursion detected (same locals & position)
在调试器中,我看到该函数是由connect_to_to_helper_with_with_with_with_test_client
connect_to_to_to_helper_with_with_with_with_with_with 对helper_app
的调用返回预期值({“ msg”:“这是辅助应用程序。”}
)。
我想了解递归的来源以及如何避免错误。提前致谢!
I would like to test the interplay with two FastAPIs using python 3.8
. In the running code, one API (main_app
) is calling the other API (helper_app
) by the function connect_to_helper_app
. To test this without setting up two servers, I would like to use fastapi.testclient.TestClient
. Unfortunately, I get a RecursionError
.
To reproduce the error, you need the following files:
# Content of minimal_example/apps.py
from fastapi import FastAPI
main_app = FastAPI()
helper_app = FastAPI()
def connect_to_helper_app():
"""
This function will be mocked in the test. In the real code, a request to the other app would be made
"""
raise NotImplemented
@main_app.get("/call_helper")
def call_helper() -> dict:
return connect_to_helper_app()
@helper_app.get("/")
def root() -> dict:
return {"msg": "This is the helper app."}
And following test file:
# Content of minimal_example/test.py
from fastapi.testclient import TestClient
from minimal_example.apps import main_app, helper_app
helper_test_client = TestClient(helper_app)
main_test_client = TestClient(main_app)
def test(mocker):
def connect_to_helper_app_with_test_client():
result = helper_test_client.get('/')
return result
mocker.patch('minimal_example.apps.connect_to_helper_app', new=connect_to_helper_app_with_test_client)
main_test_client.get('/call_helper')
The error message I get is:
test.py:7 (test)
mocker = <pytest_mock.plugin.MockerFixture object at 0x0000015DFFB93F40>
def test(mocker):
def connect_to_helper_app_with_test_client():
result = helper_test_client.get('/')
return result
mocker.patch('minimal_example.apps.connect_to_helper_app', new=connect_to_helper_app_with_test_client)
> main_test_client.get('/call_helper')
test.py:14:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\.venv\lib\site-packages\requests\sessions.py:542: in get
return self.request('GET', url, **kwargs)
..\..\.venv\lib\site-packages\starlette\testclient.py:415: in request
return super().request(
..\..\.venv\lib\site-packages\requests\sessions.py:529: in request
resp = self.send(prep, **send_kwargs)
..\..\.venv\lib\site-packages\requests\sessions.py:645: in send
r = adapter.send(request, **kwargs)
..\..\.venv\lib\site-packages\starlette\testclient.py:243: in send
raise exc from None
..\..\.venv\lib\site-packages\starlette\testclient.py:240: in send
loop.run_until_complete(self.app(scope, receive, send))
C:\Users\d91802\AppData\Local\Programs\Python\Python38\lib\asyncio\base_events.py:616: in run_until_complete
return future.result()
..\..\.venv\lib\site-packages\fastapi\applications.py:208: in __call__
await super().__call__(scope, receive, send)
..\..\.venv\lib\site-packages\starlette\applications.py:112: in __call__
await self.middleware_stack(scope, receive, send)
..\..\.venv\lib\site-packages\starlette\middleware\errors.py:181: in __call__
raise exc from None
..\..\.venv\lib\site-packages\starlette\middleware\errors.py:159: in __call__
await self.app(scope, receive, _send)
..\..\.venv\lib\site-packages\starlette\exceptions.py:82: in __call__
raise exc from None
..\..\.venv\lib\site-packages\starlette\exceptions.py:71: in __call__
await self.app(scope, receive, sender)
..\..\.venv\lib\site-packages\starlette\routing.py:580: in __call__
await route.handle(scope, receive, send)
..\..\.venv\lib\site-packages\starlette\routing.py:241: in handle
await self.app(scope, receive, send)
..\..\.venv\lib\site-packages\starlette\routing.py:52: in app
response = await func(request)
..\..\.venv\lib\site-packages\fastapi\routing.py:234: in app
response_data = await serialize_response(
..\..\.venv\lib\site-packages\fastapi\routing.py:148: in serialize_response
return jsonable_encoder(response_content)
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:107: in jsonable_encoder
jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:145: in jsonable_encoder
return jsonable_encoder(
..\..\.venv\lib\site-packages\fastapi\encoders.py:93: in jsonable_encoder
encoded_value = jsonable_encoder(
E RecursionError: maximum recursion depth exceeded in comparison
!!! Recursion detected (same locals & position)
In the debugger, I see that the function is sucessfully mocked by connect_to_helper_app_with_test_client
and within that mocked function, the call to the helper_app
returns the expected value ({"msg": "This is the helper app."}
).
I would like to understand where the recursion is coming from, and how to avoid the error. Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您应该将
connect_to_helper_app()
将其拉到单独的类中。这样,您可以嘲笑导入而不是实际实现。I think you should pull your
connect_to_helper_app()
into a separate class. This way you can mock the import instead of the actual implementation.