我有一个带有 FileField 的模型。我想对它进行单元测试。 django 测试框架有很好的方法来管理数据库和电子邮件。 FileFields 有类似的东西吗?
我如何确保单元测试不会污染实际应用程序?
提前致谢
PS:我的问题几乎是 Django test FileField using test fixtures 的副本,但没有公认的答案。只是想重新询问是否有关于此主题的新内容。
原文由 luc 发布,翻译遵循 CC BY-SA 4.0 许可协议
我有一个带有 FileField 的模型。我想对它进行单元测试。 django 测试框架有很好的方法来管理数据库和电子邮件。 FileFields 有类似的东西吗?
我如何确保单元测试不会污染实际应用程序?
提前致谢
PS:我的问题几乎是 Django test FileField using test fixtures 的副本,但没有公认的答案。只是想重新询问是否有关于此主题的新内容。
原文由 luc 发布,翻译遵循 CC BY-SA 4.0 许可协议
Django 提供了一个很好的方法来做到这一点——使用 SimpleUploadedFile
或 TemporaryUploadedFile
。 SimpleUploadedFile
如果您只需要存储一些哨兵数据,通常是更简单的选择:
from django.core.files.uploadedfile import SimpleUploadedFile
my_model.file_field = SimpleUploadedFile(
"best_file_eva.txt",
b"these are the file contents!" # note the b in front of the string [bytes]
)
这是 django 的神奇功能之一——不会出现在文档中 :)。然而,它在 这里 被引用并 在这里 实现。
请注意,您只能将 bytes
放入 SimpleUploadedFile
因为它是在幕后使用 BytesIO
实现的。如果您需要更真实的、类似文件的行为,您可以使用 TemporaryUploadedFile
。
如果 您卡在 python 2 上,请跳过内容中的 b
前缀:
my_model.file_field = SimpleUploadedFile(
"best_file_eva.txt",
"these are the file contents!" # no b
)
原文由 waterproof 发布,翻译遵循 CC BY-SA 4.0 许可协议
2 回答5.1k 阅读✓ 已解决
2 回答1.1k 阅读✓ 已解决
4 回答993 阅读✓ 已解决
3 回答1.1k 阅读✓ 已解决
3 回答1.2k 阅读✓ 已解决
1 回答1.7k 阅读✓ 已解决
1 回答1.2k 阅读✓ 已解决
有几种方法可以解决这个问题,但它们都很丑陋,因为单元测试应该是隔离的,但文件都是关于持久更改的。
我的单元测试不在具有生产数据的系统上运行,因此很容易在每次运行后使用类似
git reset --hard
重置上传目录。这种方法在某些方面是最好的,因为它不涉及代码更改,并且只要您从良好的测试数据开始就可以保证工作。如果在测试模型的保存方法后实际上不需要对该文件执行任何操作,我建议使用 python 的优秀 Mock 库 来完全伪造
File
实例(即类似于mock_file = Mock(spec=django.core.files.File); mock_file.read.return_value = "fake file contents"
) 这样您就可以完全避免更改文件处理逻辑。 Mock 库有几种方法可以在测试方法中 全局修补 Django 的 File 类,这将尽可能简单。如果您需要一个真实的文件(即作为测试的一部分,使用外部脚本处理等),您可以使用类似于 Mirko 示例的东西,并在确保将其存储在适当的地方后创建一个 File 对象- 以下是三种方法:
settings.MEDIA_ROOT
指向临时目录(请参阅 Python 临时文件 模块的mkdtemp
函数)。只要您有一个单独的STATIC_ROOT
类的东西,它就可以正常工作,您可以将其用于作为源代码一部分的媒体文件。MEDIA_ROOT
下的测试子目录。编辑: 模拟对象库是 python 3.3 版中的新内容。对于较旧的 python 版本,请检查 Michael Foord 的版本