Skip to content

TestClient.request doesn't return a context manager #3852

Closed
@nicktimko

Description

@nicktimko

Long story short

aiohttp.test_utils.TestClient.request seems to be an odd-man out in not returning a context manager.

Expected behaviour

Returns a context manager.

Actual behaviour

When calling the .request() method of TestClient, it doesn't seem to return a _RequestContextManager like the other 3 permutations.

  • ClientSession.request() -> aiohttp.client._RequestContextManager
  • ClientSession.<verb>() -> aiohttp.client._RequestContextManager
  • TestClient.request() -> aiohttp.client._RequestContextManager
  • TestClient.<verb>() -> coroutine
➜ python methodtests.py 
methodtests.py:18: RuntimeWarning: coroutine 'TestClient.request' was never awaited
  async with client.request(method, url) as resp:
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Traceback (most recent call last):
  File "methodtests.py", line 43, in <module>
    loop.run_until_complete(main())
  File "/home/nick/.pyenv/versions/3.7.2/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "methodtests.py", line 40, in main
    await check_client(client, "/")  # XXX dies
  File "methodtests.py", line 18, in check_client
    async with client.request(method, url) as resp:  # YYY dies
AttributeError: __aexit__

Steps to reproduce

import asyncio
import aiohttp.test_utils
import aiohttp.web

async def handleall(request):
    return aiohttp.web.Response()

async def check_client(client, base_url):
    for method in ["GET", "POST", "PUT", "DELETE"]:
        url = base_url + method.lower()

        # slightly awkward, but works with both client types
        clientmethod = getattr(client, method.lower())
        async with clientmethod(url) as resp:
            assert resp.status == 200

        # fails with test clients
        async with client.request(method, url) as resp:  # YYY dies
            assert resp.status == 200

async def main():
    # a "regular" ClientSession
    base_url = "https://httpbin.org/"
    async with aiohttp.ClientSession() as client:
        await check_client(client, base_url)

    app = aiohttp.web.Application()
    app.router.add_route("*", "/{verb}", handleall)

    async with aiohttp.test_utils.TestServer(app) as server:
        async with aiohttp.test_utils.TestClient(server) as test_client:
            base_url = str(test_client.make_url("/"))
            # a "regular" client created from the test client
            client = test_client.session
            await check_client(client, base_url)

    async with aiohttp.test_utils.TestServer(app) as server:
        async with aiohttp.test_utils.TestClient(server) as client:
            # just the test client
            await check_client(client, "/")  # XXX dies

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Your environment

Python 3.7.2
aiohttp 3.5.4

Activity

webknjaz

webknjaz commented on Jun 18, 2019

@webknjaz
Member

Thanks, feel free to send a PR. You may start digging @ https://github.com/aio-libs/aiohttp/blob/master/aiohttp/pytest_plugin.py

added a commit that references this issue on Aug 17, 2019

Fixes aio-libs#3852 - aiohttp.test_utils.TestClient should return a _…

0ba7d1e
added 2 commits that reference this issue on Aug 30, 2019

[3.6] Fixes #3852 - aiohttp.test_utils.TestClient should return a _Re…

6ed27b8

[3.6] Fixes #3852 - aiohttp.test_utils.TestClient should return a _Re…

0929934
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      TestClient.request doesn't return a context manager · Issue #3852 · aio-libs/aiohttp