如何在Django测试中为request传入device字段?
修复方案
首先,你的代码存在两个关键问题:
- Device类构造方法拼写错误:你写的是
__int__,正确的构造方法应该是__init__,否则实例化Device时不会初始化id属性。 - 测试Client的参数传递逻辑错误:Django测试Client的
get方法中,额外传入的参数不会直接附加到request对象上,而是作为请求的查询参数、headers或其他请求元数据,所以request.device始终为None。
修复步骤
1. 修正Device类
class Device: def __init__(self, _id): # 修复构造方法名称 self.id = _id
2. 使用RequestFactory直接测试视图(推荐)
这种方式更适合单元测试视图逻辑,直接构造Request对象并手动添加device属性:
from django.test import TestCase, RequestFactory # 导入你的视图函数,替换成实际的app和视图路径 from your_app.views import test_function class Device: def __init__(self, _id): self.id = _id class MyTest(TestCase): def test_device(self): # 创建RequestFactory实例 factory = RequestFactory() # 构造GET请求的request对象 request = factory.get('/test_end/') # 手动给request添加device属性 request.device = Device(42) # 直接调用视图函数 response = test_function(request) # 断言结果是否符合预期(注意视图需返回HttpResponse) self.assertEqual(response.content, b'42')
3. (可选)自定义Client实现参数传递
如果一定要使用Client类,可以自定义Client来处理device参数的传递:
from django.test import TestCase from django.test.client import Client from your_app.views import test_function class Device: def __init__(self, _id): self.id = _id class CustomClient(Client): def get(self, path, **extra): # 先构造request对象 request = self.request(path=path, **extra) # 从extra中取出device并附加到request if 'device' in extra: request.device = extra.pop('device') # 获取响应 response = self.get_response(request) return response class MyTest(TestCase): def test_device(self): client = CustomClient() response = client.get("/test_end/", device=Device(42)) self.assertEqual(response.content, b'42')
4. 修正视图函数(必要)
注意:Django视图必须返回HttpResponse对象,不能直接返回数字,否则会被解析为HTTP状态码,导致错误。所以视图需要调整:
from django.http import HttpResponse def test_function(request): return HttpResponse(request.device.id)
内容的提问来源于stack exchange,提问作者Avigdor Paperno
相关产品推荐
相关产品推荐

