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

Router does not honor assert_all_called #228

Closed
BeyondEvil opened this issue May 4, 2023 · 5 comments
Closed

Router does not honor assert_all_called #228

BeyondEvil opened this issue May 4, 2023 · 5 comments

Comments

@BeyondEvil
Copy link

BeyondEvil commented May 4, 2023

I'm using the router like so:

import pytest
import httpx
import respx

from syncer.workitem import WorkItem


@pytest.fixture
def router():
    router = respx.Router(base_url="https://dev.azure.com/")
    router.get(
        path__regex=r"\/workitems\/\d+$",
        name="get",
    )
    router.get(
        path__regex=r"\/workitems\/\d+\/comments$",
        name="comments-get",
    )
    router.post(
        path__regex=r"\/workitems\/\d+\/comments$",
        name="comments-post",
    )
    router.patch(
        path__regex=r"\/workitems\/\d+\/comments\/d+$",
        name="comments-patch",
    )
    return router


@pytest.fixture
def http_client(router):
    mock_transport = httpx.MockTransport(router.async_handler)
    return httpx.AsyncClient(transport=mock_transport)


@pytest.fixture
def workitem(http_client):
    def factory():
        return  WorkItem("test_org", http_client)

    return factory


async def test_fetch(router, workitem):
    router["get"].respond(json={})
    await workitem().fetch()
    assert router.routes["get"].call_count == 1
    assert router.routes["comments-get"].call_count == 0
    assert router.routes["comments-post"].call_count == 0
    assert router.routes["comments-patch"].call_count == 0

The test passes, but I would expect it to fail since I'm not calling all mocked routes (which the test itself asserts).

What I'm doing wrong or missunderstanding?

Result of "pip freeze"

anyio==3.6.2
assertpy==1.1
async-generator==1.10
attrs==23.1.0
azure-core==1.26.4
azure-servicebus==7.9.0
black==23.3.0
certifi==2022.12.7
charset-normalizer==3.1.0
click==8.1.3
exceptiongroup==1.1.1
flake8==6.0.0
flake8-bugbear==23.3.23
Flake8-pyproject==1.2.3
h11==0.14.0
httpcore==0.17.0
httpx==0.24.0
idna==3.4
iniconfig==2.0.0
isodate==0.6.1
mccabe==0.7.0
mypy-extensions==1.0.0
outcome==1.2.0
packaging==23.1
pathspec==0.11.1
pep8-naming==0.13.3
platformdirs==3.5.0
pluggy==1.0.0
pycodestyle==2.10.0
pyflakes==3.0.1
pytest==7.3.1
pytest-mock==3.10.0
pytest-trio==0.8.0
requests==2.30.0
respx==0.20.1
six==1.16.0
sniffio==1.3.0
sortedcontainers==2.4.0
-e git+https://afaforsakring2@dev.azure.com/afaforsakring2/Utvecklingsstod/_git/syncer@611d0bcb65a906f82c0927725347140eab791774#egg=syncer
tomli==2.0.1
trio==0.22.0
typing_extensions==4.5.0
uamqp==1.6.4
urllib3==2.0.2

FWIW I'm using python 3.10.6 running in WSL2 (Ubuntu 22.04) on Windows 10.

@lundberg
Copy link
Owner

lundberg commented May 5, 2023

Thanks for reporting @BeyondEvil.

You're right, assert_all_called is not evaluated when using the base Router .. only when using the MockRouter, e.g. with respx.mock():.

This is due to missing exit stack when using the httpx client like this. Meaning, assert_all_called needs to be evaluated after the/each test function, which it does when using the MockRouter either as a decorator, contextmanager or fixture with ctx+yield.

Currently I'd say you'll have to trigger it manually. Thinking out loud here, but could you try this ...

@pytest.fixture
def router():
    router = respx.Router(base_url="https://dev.azure.com/")
    # ...
    yield router
    router.assert_all_called()

Regardless if this manual approach works, we should adjust the documentation mentioning this current limitation.

Maybe even remove the assert_all_called init kwarg from Router and only have it on the MockRouter making it clear that it doesn't gets triggered automatically by the base router.

@BeyondEvil
Copy link
Author

Thanks for reporting @BeyondEvil.

You're right, assert_all_called is not evaluated when using the base Router .. only when using the MockRouter, e.g. with respx.mock():.

This is due to missing exit stack when using the httpx client like this. Meaning, assert_all_called needs to be evaluated after the/each test function, which it does when using the MockRouter either as a decorator, contextmanager or fixture with ctx+yield.

Thanks for detailed explanation!

Currently I'd say you'll have to trigger it manually. Thinking out loud here, but could you try this ...

@pytest.fixture
def router():
    router = respx.Router(base_url="https://dev.azure.com/")
    # ...
    yield router
    router.assert_all_called()

Brilliant!

Regardless if this manual approach works, we should adjust the documentation mentioning this current limitation.

Maybe even remove the assert_all_called init kwarg from Router and only have it on the MockRouter making it clear that it doesn't gets triggered automatically by the base router.

Yes and yes. 👍 😊

@lundberg
Copy link
Owner

Added a new issue #233 for this 👍

@lundberg
Copy link
Owner

Docs are now updated @BeyondEvil

@BeyondEvil
Copy link
Author

Nice! Clear and concise. 👍

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