Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aioresponses ignores custom response_class provided to aiohttp.ClientSession constructor #243

Open
hf-kklein opened this issue Jul 27, 2023 · 3 comments

Comments

@hf-kklein
Copy link
Contributor

I'm using the following code, which preserves the response body in case raise_for_status=True.
I copied it from aio-libs/aiohttp#4600 (comment) and it works in reality but not when testing with aioresponses:

import aiohttp
import pytest
from aioresponses import aioresponses


class MyClientResponse(aiohttp.ClientResponse):
    async def start(self, connection: aiohttp.connector.Connection) -> aiohttp.ClientResponse:
        result = await super().start(connection)
        if self.status >= 400:
            await self.read()  # Avoid a ClientConnectionError later
        return result

    def raise_for_status(self) -> None:
        try:
            super().raise_for_status()
        except aiohttp.ClientResponseError as err:
            try:
                coro = self.text()
                try:
                    coro.send(None)
                except StopIteration as text:
                    if text.value:
                        err.message = text.value # <-- "Internal Server Error" is replaced with "terrible crash"
                finally:
                    coro.close()
            finally:
                raise err


class TestClientResponseClass:
    async def test_mock_bypasses_session_response_class(self):
        with pytest.raises(aiohttp.ClientResponseError) as excinfo:
            with aioresponses() as mocked:
                mocked.post("https://myserver.inv/", status=500, payload="terrible crash")
                session = aiohttp.ClientSession(raise_for_status=True, response_class=MyClientResponse)
                _ = await session.post("https://myserver.inv/", json={"foo": "bar"})
        assert isinstance(excinfo.value, aiohttp.ClientResponseError) #  ok
        assert excinfo.value.message == "terrible crash" #  fails!

I cannot point my finger on it. Might be my test setup is wrong but I feel like this is an error/missing feature of aioresponses, because, as I said, it works with a real server but not with a mocked one.

@p2vvel
Copy link

p2vvel commented Dec 18, 2023

Had the same problem and resolved it by adding response_class like below:

with aioresponses() as mocked:
                mocked.post("https://myserver.inv/", status=500, payload="terrible crash", response_class=MyClientResponse)

@hf-kklein
Copy link
Contributor Author

@p2vvel So you mean: Adding the response class to the actual request instead of to the session is a workaround, right?

@p2vvel
Copy link

p2vvel commented Dec 18, 2023

Yes, I managed to use custom raise_for_status() during testing with aioresponses that way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants