Pytest / Django: How to change a decorator that is defined during build time?
I am making a network request and give it a 10 second timeout.
The timeout is raised by a decorator that reads the time limit from settings
, so it looks like this:
@timeout(settings.TIMEOUT)
.
The problem is that I want the test to be super fast, so I change the timeout to 0.1
:
settings.TIMEOUT = 0.1
The problem is that the decorator is already initialized
(I might be using the wrong word) by the time I try to test it. So the decorator is created/defined at build time, then I change the settings, but too late, the decorator doesn't read the updated setting again.
Here is a simplified version:
##############
settings.py
###############
TIMEOUT = 10
###############
request_maker.py
###############
from timeout_decorator import timeout
from django.conf import settings
from time import sleep
class MakeRequest
@timeout(settings.TIMEOUT)
def make_the_request(self):
sleep(100)
###############
tests.py
###############
import pytest
from timeout_decorator import TimeoutError
from request_maker import MakeRequest
def test_make_request(settings):
settings.TIMEOUT = 0.1
mr = MakeRequest()
with pytest.raises(TimeoutError) as e:
mr.make_the_request() # < Even though TIMEOUT is 0.1, it actually times out for 10 seconds
How can I change the code so that during production, it is @timeout(10)
and during testing it is @timeout(0.1)
?
Solution 1:
You should have the DEBUG
variable in your settings.py
and assume that you initialize this variable from .env
to determine if its production or not. Then you can initialize the TIMEOUT
variable in settings.py
depending on DEBUG
variable like this:
DEBUG = os.getenv("DEBUG") == "True"
TIMEOUT = 0.1 if DEBUG else 10