Skip to content

make_mocked_request() behavior is broken when no payload is specified #7167

Closed
@rahulnht

Description

Describe the bug

When unit testing handler/middleware behavior with a request created via make_mocked_request() method without specifying payload, ran into issues with reading its content inside handler.

Looking at the source, found problem with the an default empty mock that is assigned if payload is not explicitly specified.

To Reproduce

Run the following sample minimal script that reproduces the behavior.

from aiohttp import web
from aiohttp.test_utils import make_mocked_request
import asyncio

async def handle(request):
    print(type(request._payload))
    print(request._payload.__dict__)
    request_body = await request.read()
    return web.Response(body=request_body)

async def test():
    req = make_mocked_request('GET', '/')
    await handle(req)

app = web.Application()
app.add_routes([web.get('/', handle)])

if __name__ == '__main__':
    # web.run_app(app)
    asyncio.run(test())

Expected behavior

When running as web_app, the request to / sends 200.
When running via test, it fails. Ideally the payload should be initialized as empty so that if awaited, empty body is returned inside handler.

Logs/tracebacks

❯ python3 main.py
Traceback (most recent call last):
  File "/test-app/main.py", line 19, in <module>
    asyncio.run(test())
  File "/usr/local/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/local/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/test-app/main.py", line 11, in test
    await handle(req)
  File "/test-app/main.py", line 6, in handle
    request_body = await request.read()
  File "/test-app/venv/lib/python3.10/site-packages/aiohttp/web_request.py", line 649, in read
    chunk = await self._payload.readany()
TypeError: object Mock can't be used in 'await' expression

Python Version

$ python --version
Python 3.10.9

aiohttp Version

$ python -m pip show aiohttp
Name: aiohttp
Version: 3.8.3
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author: 
Author-email: 
License: Apache 2
Location: test-app/venv/lib/python3.10/site-packages
Requires: aiosignal, async-timeout, attrs, charset-normalizer, frozenlist, multidict, yarl
Required-by:

multidict Version

$ python -m pip show multidict
Name: multidict
Version: 6.0.4
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: /test-app/venv/lib/python3.10/site-packages
Requires: 
Required-by: aiohttp, yarl

yarl Version

$ python -m pip show yarl
Name: yarl
Version: 1.8.2
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: /test-app/venv/lib/python3.10/site-packages
Requires: idna, multidict
Required-by: aiohttp

OS

Ubuntu 22.04.1

Related component

Server

Additional context

No response

Code of Conduct

  • I agree to follow the aio-libs Code of Conduct

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions