如何为Python中@mock.patch设置model.objects.filter的返回值?
关于mock.patch设置filter返回值的问题
是的,通常需要把Mymodel实例包装成Django QuerySet对象来设置return_value,原因有两个:
- 视图中使用了
many=True的序列化器,虽然它能处理普通列表,但QuerySet是Django ORM查询的标准返回类型,更贴合真实业务场景; - 如果后续代码对filter结果调用了QuerySet特有的方法(比如二次过滤、排序、聚合等),普通列表会直接报错,而QuerySet能正常兼容这些操作。
具体实现方式
方式一:构造标准QuerySet(推荐)
可以直接用Django的QuerySet类构造,或者借助none()方法拼接实例:
from django.db.models.query import QuerySet from unittest import mock from django.test import TestCase from .views import MyView, Mymodel class MyViewTest(TestCase): @mock.patch('views.Mymodel.objects.filter') def test_MyView(self, filtered_result): # 创建模拟的模型实例 mock_instances = [ Mymodel(name="张三", age=25), Mymodel(name="李四", age=25) ] # 构造QuerySet并设置返回值 filtered_result.return_value = QuerySet(model=Mymodel, query=None, using=None) filtered_result.return_value._result_cache = mock_instances # 或者用更简洁的拼接方式 # filtered_result.return_value = Mymodel.objects.none() | mock_instances # 发起请求并断言结果 response = self.client.get('/your-view-path/') self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 2)
方式二:用普通列表(仅适用于简单场景)
如果你的视图代码只把filter结果传给序列化器,没有调用QuerySet的特殊方法,也可以直接用列表临时替代:
from unittest import mock from django.test import TestCase from .views import MyView, Mymodel class MyViewTest(TestCase): @mock.patch('views.Mymodel.objects.filter') def test_MyView(self, filtered_result): filtered_result.return_value = [ Mymodel(name="张三", age=25), Mymodel(name="李四", age=25) ] # 后续测试逻辑 response = self.client.get('/your-view-path/') self.assertEqual(response.status_code, 200)
额外提示
你的视图代码里有几处拼写错误,需要修正:
serializerClass应该是serializer_class(Django类视图的标准属性名)many=true应该是many=True(Python布尔值首字母需大写)serializert.data应该是serializer.data(变量名拼写错误)
内容的提问来源于stack exchange,提问作者Monti
相关产品推荐
相关产品推荐

