Django REST Framework单元测试发送Protobuf二进制文件无响应排查
问题分析与修复方案
你的测试代码存在几个关键问题,导致请求未按预期工作:
- 请求数据格式错误:当指定
content_type='application/octet-stream'时,DRF测试客户端不会解析data中的字典结构,你不需要把文件包装成{'file': myfile}的形式,应该直接将二进制文件内容作为data的参数值。 - 文件资源未正确管理:直接
open文件后未关闭,容易引发资源泄漏,建议用with语句自动处理文件的打开与关闭。 - URL参数处理不规范:
content-disposition作为URL参数传递不是标准用法,通常该头字段用于响应而非请求;如果后端需要文件名,建议通过自定义请求头或单独的URL参数传递。
修复后的测试代码示例:
def test_post(self): files_dir = os.path.join(settings.BASE_DIR, 'api/test_files') path = os.path.join(files_dir, 'test1_test2.bin') # 用os.path.join拼接路径更安全 with open(path, 'rb') as myfile: # 直接传入文件二进制内容作为请求数据 response = self.guest_client.post( '/config', data=myfile.read(), content_type='application/octet-stream' ) # 添加断言验证请求是否成功 self.assertEqual(response.status_code, 200) # 根据后端预期调整状态码
如果后端需要接收文件名信息,可以通过自定义请求头传递:
def test_post(self): files_dir = os.path.join(settings.BASE_DIR, 'api/test_files') path = os.path.join(files_dir, 'test1_test2.bin') with open(path, 'rb') as myfile: response = self.guest_client.post( '/config', data=myfile.read(), content_type='application/octet-stream', HTTP_X_FILENAME='test1_test2.bin' # 自定义头传递文件名 ) self.assertEqual(response.status_code, 200)
另外,你之前执行测试后“没有任何反应”,大概率是因为没有捕获并断言响应结果,添加断言语句可以帮你确认请求是否到达后端并得到正确处理。
内容的提问来源于stack exchange,提问作者Konstantinos
相关产品推荐
相关产品推荐

