【发布时间】:2009-09-21 17:49:54
【问题描述】:
在我的 Django 应用程序中,我有一段将文件上传到 Amazon S3 的代码,我想在单元测试期间跳过这一部分。单元测试恰好与DEBUG=False 一起运行,所以我无法测试settings.DEBUG == True 以跳过本节。有什么想法吗?
【问题讨论】:
标签: django unit-testing
在我的 Django 应用程序中,我有一段将文件上传到 Amazon S3 的代码,我想在单元测试期间跳过这一部分。单元测试恰好与DEBUG=False 一起运行,所以我无法测试settings.DEBUG == True 以跳过本节。有什么想法吗?
【问题讨论】:
标签: django unit-testing
您真的不想在单元测试中“跳过”代码——如果这样做,您将永远无法覆盖这些区域。为外部系统提供模拟接口要好得多,这样您就可以确保其余代码按预期运行。这在处理可能不可用的外部资源时尤其重要,因为 S3 可能会在网络问题、服务中断或配置错误的情况下发生。
或者,您可以在生产环境中使用Django S3 storage backend,同时配置测试以使用本地文件存储。
【讨论】:
您可以 - 是的,这是一个 hack - 导入执行上传的模块,并将该模块中的上传函数替换为另一个函数,它什么都不做。像这样的:
foo.py:
def bar():
return 42
biz.py:
import foo
print foo.bar() # prints 42
foo.bar = lambda: 37
print foo.bar() # prints 37
同样,这是一个 hack,但如果这是您需要此类功能的唯一地方,它可能对您有用。
【讨论】:
您不会跳过测试功能。
您为不想像生产一样运行的东西提供模拟实现。
首先,您通过使 S3 Uploader 成为一个单独的类来设计测试,该类具有您的应用程序所需的 API。
然后您使用相同的 API 编写此类的模拟版本。它所做的只是记录它被调用。
最后,您要确保您的单元测试插入您的模拟对象而不是真正的 S3 上传器。
您的 Django 应用程序不应进行任何更改 -- 除了单元测试“注入”到其中的更改。
上传的views.py
import the_uploader
import mock_uploader
from django.conf import settings
uploadClass = eval( settings.S3_UPLOAD_CLASS_NAME )
uploader= uploadClass( ... )
现在,您提供两个 settings.py 文件。默认的 settings.py 具有正确的上传器类名称。
为了测试,你有一个test_settings.py,看起来像这样。
import settings.py
S3_UPLOAD_CLASS_NAME = "mock_uploader.mock_upload_class"
这使您可以实际测试所有内容。
【讨论】: