You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过mock.patch将ViewSet.filterset_class设为返回None?

问题描述

编写了如下测试代码,意图通过@mock.patch禁用MyViewSet的filterset_class,避免查询参数影响视图行为:

@mock.patch("app.views.MyViewSet.filterset_class", return_value=None)
def test_filter_chat_request_management_status(self, mock_filterset_class):
    query_parameter = "status=accepted"
    response = self.client.get(URL + "?" + query_parameter)
    assert 1 == 1

但调试时发现,测试方法作用域内MyViewSet.filterset_class返回的是MagicMock对象而非预期的None:

>>> print(MyViewSet.filterset_class)
<MagicMock name='filterset_class' id='4894544640'>

导致DRF的DjangoFilterBackend.get_filterset_class()方法中,getattr(view, "filterset_class", None)拿到的是MagicMock实例,无法达到禁用过滤的效果。

解决方案

问题出在return_value参数的用法上:该参数仅对被mock的方法生效,而你mock的是类属性,patch默认会将目标属性替换为MagicMock实例,return_value在这里不起作用。

有两种方法可以强制让MyViewSet.filterset_class返回None:

方法一:使用new参数直接替换为None

修改patch装饰器,通过new=None直接将目标属性设置为None,无需接收mock参数:

@mock.patch("app.views.MyViewSet.filterset_class", new=None)
def test_filter_chat_request_management_status(self):
    query_parameter = "status=accepted"
    response = self.client.get(URL + "?" + query_parameter)
    assert 1 == 1

方法二:在测试方法内手动覆盖mock对象

如果需要保留mock参数(比如后续要做断言),可以在方法内部直接将mock对象赋值为None:

@mock.patch("app.views.MyViewSet.filterset_class")
def test_filter_chat_request_management_status(self, mock_filterset_class):
    mock_filterset_class = None
    query_parameter = "status=accepted"
    response = self.client.get(URL + "?" + query_parameter)
    assert 1 == 1

这两种方法都会让后续访问MyViewSet.filterset_class时得到None,从而让DRF的过滤逻辑跳过该属性,达到禁用过滤的目的。

内容的提问来源于stack exchange,提问作者Ivan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:53:17