基于DRF ModelViewSet实现的视图类可编写哪些单元测试?
针对继承DRF ModelViewSet 的这类标准视图集,编写单元测试时不需要重复覆盖DRF框架本身已经实现的通用逻辑,只需要验证你在类中自定义的配置、扩展逻辑是否符合预期,即可完成全测试覆盖。
你给出的示例类代码如下:
class ExampleViewSet(viewsets.ModelViewSet): serializer_class = ExampleSerializer queryset = Example.objects.all() filter_backends = (filters.DjangoFilterBackend,) filterset_class = ExampleFilter
基础配置正确性测试
这类测试用来防止改配置时出现手误,属于低成本高收益的校验项:
- 校验视图集绑定的
serializer_class属性值为你预期的ExampleSerializer,避免绑定错序列化器导致接口返回字段异常 - 校验视图集绑定的
queryset对应的模型为Example,默认查询范围符合预期(如果后续重写了get_queryset方法,再追加对应自定义逻辑的测试即可) - 校验过滤器配置正确:
filter_backends确实包含DjangoFilterBackend,绑定的filterset_class为你自定义的ExampleFilter,避免配置遗漏导致过滤功能失效
标准CRUD接口行为测试
这部分只需要验证接口在你的配置下行为符合预期,不需要测试DRF内置的核心逻辑:
- 列表接口:
- 按你项目配置的权限规则,校验无权限用户访问返回401/403,有权限用户访问返回200
- 验证返回的结果字段和
ExampleSerializer定义的输出字段完全一致,不会多出未暴露字段、也不会缺失配置的返回字段 - 提前创建测试数据后,验证接口能正确返回查询范围内的所有实例
- 详情接口:
- 传入存在的资源ID时,返回200状态码和对应实例的正确序列化数据
- 传入不存在的资源ID时,返回404状态码
- 创建接口:
- 传入符合
ExampleSerializer校验规则的合法参数时,返回201状态码,数据库中成功创建对应Example实例,返回数据和新创建的实例信息一致 - 传入不符合校验规则的参数(缺必填项、字段格式错误、外键不存在等)时,返回400状态码和对应错误提示,数据库不会写入脏数据
- 传入符合
- 更新接口(含PUT全量更新、PATCH部分更新):
- 传入合法更新参数时,返回200状态码,数据库中对应实例的字段被正确修改,返回数据和更新后的实例信息一致
- 传入非法更新参数时,返回400状态码,实例原有数据不会被改动
- 传入不存在的资源ID时,返回404状态码
- 删除接口:
- 传入存在的资源ID时,返回204状态码,数据库中对应实例被正确删除
- 传入不存在的资源ID时,返回404状态码
过滤功能专项测试
由于你显式配置了自定义过滤器类,这部分属于必须覆盖的自定义逻辑:
- 针对
ExampleFilter中定义的每一个过滤字段,构造对应测试场景:比如过滤器支持按status字段过滤,就提前创建多个status取值不同的测试数据,传入对应过滤参数后,验证返回结果仅包含符合过滤条件的实例,不符合条件的数据不会出现在返回列表中 - 传入非法过滤参数(比如过滤字段不存在、字段值类型不匹配)时,验证接口不会抛出500服务端错误,返回结果符合预期(空结果或400参数错误,按你FilterSet的配置逻辑判定)
- 不传任何过滤参数时,验证返回结果和默认queryset的查询范围一致,不会出现非预期的过滤逻辑
多同类视图集测试优化
由于你views模块下有多个同结构的ViewSet,不需要为每个类重复编写测试代码:
- 可以封装一个通用的ModelViewSet测试基类,把上述通用测试逻辑全部封装到基类中,每个具体视图集的测试类只需要传入对应配置项:视图集类、绑定的序列化器类、对应模型类、合法创建参数样例、合法更新参数样例、过滤字段测试样例,即可自动完成所有通用用例的执行,大幅降低重复代码量。
内容的提问来源于stack exchange,提问作者Ivan Campelo
相关产品推荐
相关产品推荐

