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

Django DRF接口测试:如何校验返回的JSON对象列表中包含指定对象

问题原因分析

你遇到的两个报错均是用法错误导致的:

  • assertIn报错:参数顺序写反,assertIn的语法为assertIn(待查找元素, 容器),你误将返回的列表作为第一个参数、单个对象作为第二个参数,Python会尝试将列表作为字典的key进行哈希计算,而列表属于不可哈希类型,因此抛出TypeError: unhashable type: 'ReturnList'。
  • assertContains报错:assertContains默认用于匹配响应的原始字符串内容,你直接传入Python字典对象,它会将字典转为普通字符串和JSON响应正文做匹配,二者格式(引号、空格等)不匹配,因此测试不通过。
最优实现方案

提供两种常用的实现方式,可根据场景选择:

方案1:修正assertIn用法(最简单,适合完全匹配场景)

DRF返回的response.data中的ReturnList、ReturnDict本质是Python原生list、dict的子类,直接调整参数顺序即可正常比较:

def test_list(self):      
    client = APIClient()
    response = client.get('/api/some_list/', format='json')
    self.assertEqual(len(response.data), 19)
    # 调整参数顺序,待查找对象在前,返回列表在后
    self.assertIn(
        {"id": 2, "name": "WhatToDo"},
        response.data
    )

方案2:遍历校验(兼容性最强,支持部分字段匹配)

如果允许返回的对象包含额外字段、仅需校验指定键值对匹配,或者担心Python版本导致的字典顺序问题,可以用any()遍历判断:

def test_list(self):      
    client = APIClient()
    response = client.get('/api/some_list/', format='json')
    self.assertEqual(len(response.data), 19)
    expected = {"id": 2, "name": "WhatToDo"}
    # 完全匹配场景:判断是否有元素和expected完全相等
    has_target = any(item == expected for item in response.data)
    # 部分匹配场景(仅校验指定键值对,忽略其他字段):
    # has_target = any(all(item.get(k) == v for k,v in expected.items()) for item in response.data)
    self.assertTrue(has_target, "响应列表中未找到指定对象")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:57:04