question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Missing query param `args` when using dependency_overrides

See original GitHub issue

First check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn’t find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google “How to X in FastAPI” and didn’t find any information.
  • I already read and followed all the tutorial in the docs and didn’t find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.
  • After submitting this, I commit to one of:
    • Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
    • I already hit the “watch” button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
    • Implement a Pull Request for a confirmed bug.

Example

Note that this is not a self-contained example (extracting the database code into something others would be able to easily run proved challenging), but hopefully its enough to illustrate the problem:

main.py

from fastapi import Depends, FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session

import database

app = FastAPI()
templates = Jinja2Templates(directory="templates/")

def get_db():
    """Get and manage closure of database."""
    db_session = database.get_session()
    db = db_session()
    try:
        yield db
    finally:
        db.close()

@app.get("/", response_class=HTMLResponse)
async def home(
    request: Request,
    db: Session = Depends(get_db),
    param1="",
    param2="",
):
    # do stuff
    return templates.TemplateResponse(
            "home.html",
            {
                "request": request,
                "param1": param1,
                "param2": param2,
            },
        )

conftest.py

import unittest.mock as mock
import pytest
from fastapi.testclient import TestClient
import sqlalchemy
from main import app

@pytest.fixture
def test_app_mock_db():
    """Create a TestClient and mock out the database."""
    # Use FASTAPI's mocking framework to replace the get_db dependency with a
    # mock
    #
    # Note that this is implemented on the app object itself and so will persist
    # until undone
    app.dependency_overrides[main.get_db] = mock.MagicMock(
        spec=sqlalchemy.orm.Session
    )
    with TestClient(app) as client:
        yield client

    # remove the mock at the end of the test
    del app.dependency_overrides[main.get_db]

test_home.py


def test_home(test_app_mock_db):
    """Verify home page is created properly."""
    response = test_app_mock_db.get("/")
    print(response.json())
    assert response.status_code == 200

Description

When attempting to test and endpoint, I’m getting a 422 response and

{'detail': [{'loc': ['query', 'args'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['query', 'kwargs'], 'msg': 'field required', 'type': 'value_error.missing'}]}

args is not the name of any of the parameters the endpoint takes, so its unclear why FASTAPI thinks its missing. I’ve been unable to find problems similar to this by searching google with that error information, so it appears that its not common for this to occur.

I have several other endpoints returning TemplateResponses for which this problem does not occur (I get HTTP 200 in the tests). It seems to only affect the endpoints which use the database, which I’m attempting to mock in my fixture, and affects the tests for all endpoints which use the database.

I can confirm that get_db is getting overridden and is not being called (since it throws an error in my test environment), however I do not know why mocking it appears to make FASTAPI expects an args query parameter.

For kicks and giggles, I’ve tried modifying my test query to provide an args query parameter:

    response = test_app_mock_db.get("/?args=True")

which yields the error:

{'detail': [{'loc': ['query', 'kwargs'], 'msg': 'field required', 'type': 'value_error.missing'}]}

If I also pass in kwargs:

    response = test_app_mock_db.get("/?args=True&kwargs=True")

I do indeed get a 200 back, but clearly this is incorrect usage since FASTAPI should not expect python’s args/kwargs as query parameters???

What is the proper way to mock out the database calls in this context?

Environment

  • OS: Ubuntu
  • FastAPI Version: 0.65.0
  • Python version: 3.8.5

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:9
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

4reactions
Mausecommented, Aug 9, 2021

Try

app.dependency_overrides[get_db] = lambda: unittest.mock.MagicMock()

Instead

2reactions
klaa97commented, Jul 12, 2022

The problem of the signature is specific to MagicMock, which must be able to be called with any parameters (therefore, the signature is *args, **kwargs). FastAPI to check the dependencies simply inspect the signature, therefore you get those missing parameters error. Check out the code in FastAPI.

A simple solution would be to do something like this:

from mock import create_autospec

app.dependency_overrides[Foo] = create_autospec(lambda: None)

The main advantage is that you keep a mock as your dependency, therefore you can assert whether it has been called for example.

It works due to the fact that lambda: None has an empty signature, and Python mocks support the signature injection after Python 3.8.

Read more comments on GitHub >

github_iconTop Results From Across the Web

rest - What status code to use when a parameter is missing in ...
Let's say, user send the query parameter and you did not find any ... URI is valid but parameters are missing so 400...
Read more >
Testing Dependencies with Overrides - FastAPI
In this case, you can override the dependency that calls that provider, and use a custom dependency that returns a mock user, only...
Read more >
Query parameter targeting - Optimize Resource Hub
Query parameter targeting. Target experiments based on a query parameter in the URL. Optimize can check query parameters and use them in targeting...
Read more >
Describing Parameters - Swagger
Query string parameters may only have a name and no value, like so: GET /foo?metadata. Use allowEmptyValue to describe such parameters ...
Read more >
Use parameters in queries, forms, and reports
Note: If a parameter is configured to accept text data, any input is interpreted as text, and no error message is displayed. To...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found