如何在Python中断言接口返回的是PDF文件?
问题:如何Mock并断言接口返回的PDF文件?
我正在测试接口是否返回PDF文件,当前测试代码如下:
@mock.patch('path.to.class._get_file', return_value=MockResponse(status.HTTP_200_OK, 'application/pdf')) def test_get_should_successfully_return_the_requested_pdf(self, get_file_mock): response = self.client.get(f'/api/v1/path/to/file/abc123.pdf', content_type='application/vnd.api+json') self.assertEqual(response.status_code, status.HTTP_200_OK) # 正常生效 self.assertEqual(response['Content-Type'], 'application/pdf') # 正常生效 self.assertEqual(response, <abc123.pdf>) # 无法正常断言
打印response结果为:
print(response) <HttpResponse status_code=200, "application/pdf"
我认为@patch的设置有误,尤其是status.HTTP_200_OK, 'application/pdf'这部分。我需要确认返回的确实是PDF文件,该如何调整Mock设置以完成断言?
解决方案
1. 修正MockResponse的参数传递
你的Mock设置只指定了状态码和Content-Type,但没有传入实际的PDF内容。MockResponse通常需要接收响应体数据作为参数(字节形式的PDF内容),而非仅状态码和类型。
假设你的MockResponse构造函数是MockResponse(status_code, content, content_type)这类格式,调整patch的返回值:
# 准备模拟的PDF字节数据(可以用真实PDF的二进制内容,或简化的合法PDF结构) mock_pdf_content = b'%PDF-1.4\n%âãÏÓ\n1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] >>\nendobj\nxref\n0 4\n0000000000 65535 f \n0000000010 00000 n \n0000000079 00000 n \n0000000173 00000 n \ntrailer\n<< /Size 4 /Root 1 0 R >>\nstartxref\n262\n%%EOF' @mock.patch('path.to.class._get_file', return_value=MockResponse(status.HTTP_200_OK, content=mock_pdf_content, content_type='application/pdf')) def test_get_should_successfully_return_the_requested_pdf(self, get_file_mock): response = self.client.get(f'/api/v1/path/to/file/abc123.pdf', content_type='application/vnd.api+json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response['Content-Type'], 'application/pdf') # 新增响应体断言 self.assertEqual(response.content, mock_pdf_content)
如果MockResponse的参数顺序是(status_code, content_type, content),对应调整参数位置即可。
2. 合理选择断言方式
- 精确匹配:如果需要验证返回的是指定PDF,直接断言响应内容和Mock的二进制数据一致,如上面代码所示。
- 模糊验证:如果只需确认是PDF格式,无需精确内容,可以检查响应体的标志性开头:
self.assertTrue(response.content.startswith(b'%PDF-'))
3. 验证Mock方法的调用(可选)
如果要确认_get_file被正确触发并传入了预期参数,添加以下断言:
get_file_mock.assert_called_once_with('abc123.pdf') # 根据实际业务逻辑调整入参
内容的提问来源于stack exchange,提问作者Damon
相关产品推荐
相关产品推荐

