Pytest / Django:如何更改在构建时定义的装饰器?

Pytest / Django: How to change a decorator that is defined during build time?

我正在发出网络请求并给它一个 10 秒的超时时间。 超时由装饰器引发,该装饰器从 settings 读取时间限制,因此它看起来像这样:

@timeout(settings.TIMEOUT).

问题是我希望测试速度超快,所以我将超时更改为 0.1:

settings.TIMEOUT = 0.1

问题是当我尝试测试时,装饰器已经 initialized(我可能用错了词)。所以装饰器在构建时是 created/defined,然后我更改设置,但为时已晚,装饰器不再读取更新的设置。

这是一个简化版本:

##############
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

如何更改代码,以便在生产期间为 @timeout(10) 而在测试期间为 @timeout(0.1)

您的 settings.py 中应该有 DEBUG 变量,并假设您从 .env 初始化此变量以确定其是否生成。然后你可以根据 DEBUG 变量初始化 settings.py 中的 TIMEOUT 变量,如下所示:

DEBUG = os.getenv("DEBUG") == "True"
TIMEOUT = 0.1 if DEBUG else 10

为了解决这个问题,我做了两件事:

  1. 我改变了模块的加载方式:
import request_maker
  1. 更新设置后我重新加载了模块
settings.TIMEOUT = 0.1
reload(request_maker)

这是完整的新代码:

###############
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!