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

Django单元测试mock.patch无法正确mock依赖类属性的解决方法

Django单元测试mock.patch不生效解决方法

核心规则

mock.patch 必须patch被测模块中实际使用的依赖引用,而非依赖本身的定义路径;同时patch.object仅支持指定目标对象的直接属性名,不支持点分隔的嵌套路径。

之前写法的错误原因

  • 直接patch CctSerializer.data 不生效:data是序列化器实例的动态属性,类层面的属性patch会被实例初始化逻辑覆盖,无法作用到getAll()函数内部新建的序列化器实例。
  • @mock.patch.object(CctDAO, 'CctSerializer.data', ...) 报错:patch.object的第二个参数只能传目标对象的直接属性名,CctDAO模块下只有CctSerializer属性,不存在名为CctSerializer.data的直接属性,因此抛出属性不存在错误。
  • 注释掉的CCT.objects.all patch路径本身正确,未生效通常是因为未配置return_value,或是模块路径大小写拼写错误(贴出的代码中存在MyApp/Myapp两种大小写写法,Python模块导入大小写敏感,路径错误会直接导致mock失效)。

正确写法示例

方案1:Mock数据库查询层(推荐)

直接patch CctDAO模块内引用的CCT模型的查询方法,不需要修改序列化逻辑,更贴近真实业务执行流程:

from unittest import TestCase, mock
from .DataAccessLayer import CctDAO

class Test_CCT_DAO(TestCase):
    # 注意路径是CctDAO模块下导入的CCT,不是models文件中定义的CCT
    @mock.patch('apps.MyApp.DataAccessLayer.CctDAO.CCT.objects.all')
    def test_getall_empty(self, mock_cct_all):
        # 空数据场景
        mock_cct_all.return_value = []
        self.assertEqual([], CctDAO.getAll())

        # 带数据场景
        mock_cct_all.return_value = ['mock_entity_1', 'mock_entity_2']
        # 此处会走真实序列化逻辑,如果需要跳过序列化可以搭配方案2使用

方案2:Mock序列化器返回值

如果不需要验证序列化逻辑,可以直接patch序列化器类,手动指定data属性的返回值:

from unittest import TestCase, mock
from .DataAccessLayer import CctDAO

class Test_CCT_DAO(TestCase):
    @mock.patch('apps.MyApp.DataAccessLayer.CctDAO.CctSerializer')
    def test_getall_mock_data(self, mock_serializer_cls):
        # 配置mock序列化器实例的返回值
        mock_serializer = mock.Mock()
        mock_serializer.data = ['mocked-data1']
        # 让CctSerializer()实例化时返回我们配置的mock对象
        mock_serializer_cls.return_value = mock_serializer

        result = CctDAO.getAll()
        self.assertEqual(['mocked-data1'], result)
        # 可选:验证序列化器是否按预期参数调用
        mock_serializer_cls.assert_called_once_with(mock.ANY, many=True)

注意:请确保patch路径的大小写和实际文件路径完全一致,路径拼写错误是mock不生效的高频原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:09:21