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)?
CodePudding user response:
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
CodePudding user response:
To fix this I did 2 things:
- I changed the way the module is loaded:
import request_maker
- I reloaded the module after I updated the settings
settings.TIMEOUT = 0.1
reload(request_maker)
Here is the full new code:
###############
tests.py
###############
import pytest
from timeout_decorator import TimeoutError
import request_maker
from importlib import reload
def test_make_request(settings):
settings.TIMEOUT = 0.1
reload(request_maker)
mr = request_maker.MakeRequest()
with pytest.raises(TimeoutError) as e:
mr.make_the_request() # < Sleeps for 0.1 seconds only!
