As I am switching from Django to FastAPI, I also need to change tests from unittests to pytests. I build a custom TestAPI class and have test cases as methods, which works fine. However I want to override some functions (not dependencies) which are used in the code in one testcase. I tried this, but it doesn't work:
def test_smoke_me_api(self, monkeypatch):
monkeypatch.setattr("app.auth.utils.get_user", mock_get_user)
re = self.c.get("/me/")
It doesn't call the mock_get_user function, but instead the get_user one. According to some docs, I added the monkeypatch to the setup_class function of my test class, but this didn't work as this is apparently initialized with one argument only (self).
self.c is a client, which is a TestClient initialized in the setup_class.
Minimal example:
app/auth/utils.py
def get_user(sub) -> dict:
re = requests.get(f"https://{API_DOMAIN}/api/v2/users/{sub}")
return re.json()
app/auth/views.py
from app.auth.utils import get_user
@router.get("/")
async def me_get(sub: str = Security(auth.verify)) -> dict:
return get_user(sub)
app/test_main.py
def mock_get_user(sub = "testing") -> dict:
return {
"created_at": "2023-08-15T13:25:31.507Z",
"email": "[email protected]"
}
class TestAPI:
def setup_class(self):
from app.main import app
self.c = TestClient(app)
def test_smoke_me_api(self, monkeypatch):
monkeypatch.setattr("app.auth.utils.get_user", mock_get_user)
re = self.c.get("/me/")
When in
app.auth.viewsyou runfrom app.auth.utils import get_user, you're creating a new reference to the original functionget_userinside theapp.auth.viewsmodule.Patching
app.auth.utils.get_userchanges the reference inapp.auth.utils, but it leavesapp.auth.viewswith the copy it previously made.There are two general approaches to fixing this:
importthe module, not the function.That is to say, do something more like
import app.auth.utils as auth_utils, then callauth_utils.get_user()to refer back through the namespace to which you're applying the monkeypatchMonkeypatch the destination, not the source
That is to say, instead of monkeypatching
app.auth.utils.get_user, monkeypatchapp.auth.views.get_user().