Colin-b / pytest_httpx

pytest fixture to mock HTTPX
https://colin-b.github.io/pytest_httpx/
MIT License
344 stars 32 forks source link

Can one add mocked responses *after* creating the HTTPX client? #143

Closed bfontaine closed 5 months ago

bfontaine commented 5 months ago

Hello, I’m getting the HTTPX client as a feature, so it’s already created by the time I mock responses:

# conftest.py
@pytest.fixture(scope="function")
async def client(app):
    # ...

    async with AsyncClient(app=app, base_url="http://test") as c:
        yield c

# test file
async def test_foo(client, httpx_mock: HTTPXMock):
    httpx_mock.add_response(url="...", json={...})
    r = await client.get("/")
    assert r.json() == {...}

However this doesn’t seem to work; the test fails because the URL doesn’t match and the mocked response is never requested.

It works if I move the add_response inside the client fixture, just before the async with, but then the mock applies to all tests and so fails in all but one because the mocked response is never requested.

Is there some way to make this work?

Colin-b commented 5 months ago

Can you try moving the httpx_mock fixture before client in the test signature, as in:

# conftest.py
@pytest.fixture(scope="function")
async def client(app):
    # ...

    async with AsyncClient(app=app, base_url="http://test") as c:
        yield c

# test file
async def test_foo(httpx_mock, client):
    httpx_mock.add_response(url="...", json={...})
    r = await client.get("/")
    assert r.json() == {...}
bfontaine commented 5 months ago

Thank you. After debugging the issue it turns out that my code wasn’t even working by moving the add_response inside the client fixture because I mixed things up: I’m testing an API with HTTPX, but this API calls an external API using requests, and I was trying to mock that external API with pytest_httpx, which of course cannot work.