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

如何为Django中返回JSON数据的视图创建单元测试

Django JSON列表视图单元测试实现方案

这类直接返回模型全量字段JSON列表的视图,测试核心覆盖三个维度即可:视图可正常访问、响应格式符合JSON要求、返回内容和数据库存储数据完全一致。如果项目中存在大量同类型视图,可以抽取公共测试基类减少重复代码。

单视图基础测试写法

使用Django内置的测试框架就能完成,不需要额外引入第三方依赖,基础测试代码示例如下:

from django.test import TestCase, Client
from .models import Us
import json

class TestUserJsonListView(TestCase):
    def setUp(self):
        # 测试前置初始化:创建测试客户端、构造测试数据、配置目标路由
        self.client = Client()
        self.user1 = Us.objects.create(name="张三", age=20, email="zhangsan@test.com")
        self.user2 = Us.objects.create(name="李四", age=22, email="lisi@test.com")
        self.target_url = "/your/actual/json_list_user/route/"  # 替换为视图绑定的真实路由

    def test_view_access_normal(self):
        # 校验视图可正常访问,响应格式正确
        resp = self.client.get(self.target_url)
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(resp["Content-Type"], "application/json")

    def test_response_data_match_db(self):
        # 校验返回的JSON内容和数据库数据一致
        resp = self.client.get(self.target_url)
        resp_data = json.loads(resp.content)
        # 先校验返回数据条数
        self.assertEqual(len(resp_data), Us.objects.count())
        # 逐字段校验内容
        self.assertEqual(resp_data[0]["id"], self.user1.id)
        self.assertEqual(resp_data[0]["name"], self.user1.name)
        self.assertEqual(resp_data[0]["age"], self.user1.age)
        self.assertEqual(resp_data[0]["email"], self.user1.email)
        self.assertEqual(resp_data[1]["id"], self.user2.id)
        self.assertEqual(resp_data[1]["name"], self.user2.name)
        self.assertEqual(resp_data[1]["age"], self.user2.age)
        self.assertEqual(resp_data[1]["email"], self.user2.email)

多同类型视图复用方案

针对多个结构相同的JSON列表视图,可以抽取公共测试基类,新增视图时只需要配置3个基础参数就能完成全量基础测试,不需要重复写校验逻辑:

from django.test import TestCase, Client
import json

class BaseJsonListTestCase(TestCase):
    # 子类需要覆盖以下三个配置项
    view_route = None
    related_model = None
    test_dataset = []

    def setUp(self):
        self.client = Client()
        # 批量构造测试数据
        self.created_records = []
        for item in self.test_dataset:
            obj = self.related_model.objects.create(**item)
            self.created_records.append(obj)

    def test_base_access_and_format(self):
        # 公共校验:访问状态码、响应格式
        self.assertIsNotNone(self.view_route, "请配置视图对应的路由地址")
        self.assertIsNotNone(self.related_model, "请配置视图关联的模型类")
        resp = self.client.get(self.view_route)
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(resp["Content-Type"], "application/json")

    def test_data_consistency(self):
        # 公共校验:返回数据和数据库一致
        resp = self.client.get(self.view_route)
        resp_data = json.loads(resp.content)
        self.assertEqual(len(resp_data), self.related_model.objects.count())
        # 逐字段对比,自动处理时间类字段的序列化格式差异
        for idx, record in enumerate(self.created_records):
            db_record = self.related_model.objects.filter(id=record.id).values().first()
            for key, val in db_record.items():
                if hasattr(val, "isoformat"):
                    serialized_val = val.isoformat().replace("+00:00", "Z") if "T" in val.isoformat() else val.isoformat()
                    self.assertEqual(resp_data[idx][key], serialized_val)
                else:
                    self.assertEqual(resp_data[idx][key], val)


# 新增同类型视图的测试只需要以下几行代码
class TestUserListView(BaseJsonListTestCase):
    view_route = "/api/user/list/"
    related_model = Us
    test_dataset = [
        {"name": "张三", "age": 20, "email": "zhangsan@test.com"},
        {"name": "李四", "age": 22, "email": "lisi@test.com"}
    ]

# 比如其他商品列表、分类列表的JSON视图,直接继承基类配置即可
class TestGoodsListView(BaseJsonListTestCase):
    view_route = "/api/goods/list/"
    related_model = Goods
    test_dataset = [
        {"goods_name": "矿泉水", "price": 2, "stock": 1000},
        {"goods_name": "可乐", "price": 3.5, "stock": 500}
    ]

注意事项

  • 如果视图配置了登录、权限校验逻辑,在setUp方法里提前完成测试用户登录,或是给测试请求加上合法的认证头即可,不需要改动核心测试逻辑
  • 如果视图支持筛选、分页、排序参数,只需要在对应视图的测试类里补充单独的测试方法,传入不同参数校验返回结果即可,基础的访问、格式、全量数据校验逻辑直接复用基类
  • 示例视图里JsonResponse传入了safe=False参数,允许返回非字典类型的JSON结构,测试时不需要强制校验响应根节点为字典,只要可以正常被JSON解析、数据和数据库存储内容匹配就符合预期
  • Django测试框架运行用例时会自动创建隔离的测试数据库,所有测试过程中生成的测试数据都会在用例跑完后自动清除,不会污染开发、生产环境的业务数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:06:22