我有一个定制的throttle类,比如:(print语句用于调试api.throttle.py
print("befor CustomThrottle class")
class CustomThrottle(BaseThrottle):
def __init__(self):
super().__init__()
print("initializing CustomThrottle", self)
self._wait = 0
def allow_request(self, request, view):
print("CustomThrottle.allow_request")
if request.method in SAFE_METHODS:
return True
# some checking here
if wait > 0:
self._wait = wait
return False
return True
def wait(self):
return self._wait
我的api.views.py
是这样的:
from api.throttle import CustomThrottle
print("views module")
class SomeView(APIView):
print("in view")
throttle_classes = [CustomThrottle]
def post(self, request, should_exist):
# some processing
return Response({"message": "Done."})
我的测试是api/tests/test_views.py
:
@patch.object(api.views.CustomThrottle, "allow_request")
def test_can_get_confirmation_code_for_registered_user(self, throttle):
throttle.return_value = True
response = self.client.post(path, data=data)
self.assertEqual(
response.status_code,
status.HTTP_200_OK,
"Should be successful",
)
@patch("api.views.CustomThrottle")
def test_learn(self, throttle):
throttle.return_value.allow_request.return_value = True
response = self.client.post(path, data=data)
self.assertEqual(
response.status_code,
status.HTTP_200_OK,
"Should be successful",
)
第一个测试正确通过,但仍然实例化了CustomThrottle
类,但模拟了allow_request
方法;第二个测试显示CustomThrottle
类和allow_request
方法都没有被模拟,并且它在status 429
时失败(CustomThrottle
的节流速率为2分钟)
如果您还想模拟
CustomThrottle
类及其属性,那么您还需要在需要它的地方patch
,因为patch
decorator在调用它的地方应用monkey patching
关于你的情况,你可以做如下事情
它将用
mocked
对象替换您的real
对象,也可以签出unittest.mock documentation,它将在将来帮助您在花了一些时间并测试了不同的场景(在这里和那里放置类似调试的打印语句)之后,我终于找到了它不起作用的原因,,但它可能没有我认为的那么正确,所以欢迎任何更好的答案
我定义了
throttle_classes = [CustomThrottle]
等节流类的列表,所以当服务器启动时,它会被导入和评估,所以在我的SomeView
类中有一个对CustomThrottle
的实际版本和未修改版本的引用,当处理响应时,它会将其用于实例化,因此我的测试失败,但当我像patch.object(CustomThrottle, "allow_request")
一样修补它时当视图实际需要检查节流时,它将调用类似CustomThrottle().allow_request(...)
(注意对象创建时的括号);对象本身没有类似allow_request
的方法,因此它在其类中搜索该方法并正确使用模拟版本相关问题 更多 >
编程相关推荐