如何在单元测试中优雅地换出(补丁)Django FileSystemStorage设置?

nvi*_*vie 4 django settings storage unit-testing patch

我遇到了以下问题.我有一个看起来像这样的模型:

class Package(models.Model):
    name = models.CharField(max_length=64)
    file = models.FileField(upload_to="subdir",
                            storage=settings.PACKAGE_STORAGE,
                            null=True)
Run Code Online (Sandbox Code Playgroud)

此示例中必不可少的是构造函数的storage=参数FileField.它充满了一个值settings.py.在以下代码中:

from django.core.files.storage import FileSystemStorage
PACKAGE_STORAGE = FileSystemStorage(location="/var/data", base_url="/")
Run Code Online (Sandbox Code Playgroud)

对于生产用途,这很好.但在我的单元测试中,我现在编写的上传/var/data内容包含生产数据.我试着换出PACKAGE_STOREpackages/tests.py这样的

from django.conf import settings     # This is line 1
from tempfile import mkdtemp
settings.PACKAGE_STORAGE = FileSystemStorage(location=mkdtemp(), base_url="/")

# rest of the imports and testing code below
Run Code Online (Sandbox Code Playgroud)

但真正的问题是,加载测试文件之前,packages应用程序及其模型已经加载,因此,PACKAGE_STORAGE在我能够在测试设置代码中更改之前,设置已经解决.

是否有一种优雅的方法可以在测试环境中覆盖此特定设置?

mes*_*ntz 8

不知道这是否算优雅,但您可以使用不同的设置文件进行测试......

就像是:

# test_settings.py

from settings import *

PACKAGE_STORAGE = FileSystemStorage(location='/test/files', base_url="/")
Run Code Online (Sandbox Code Playgroud)

然后使用测试设置运行测试python manage.py test --settings=test_settings.


Tom*_*gli 5

如果您通过 django 运行测试,这应该可以工作

if 'test' in sys.argv:
    settings.DEFAULT_FILE_STORAGE = FileSystemStorage(location=mkdtemp(), base_url="/")
Run Code Online (Sandbox Code Playgroud)

当然之后;)

DEFAULT_FILE_STORAGE = FileSystemStorage(location="/var/data", base_url="/")
Run Code Online (Sandbox Code Playgroud)


Fil*_*vić 5

FileField动态覆盖模型实例的底层存储实现:

def setUp(self):
     self._field = Package._meta.get_field_by_name('file')[0]
     self._default_storage = self._field.storage
     test_storage = FileSystemStorage(location=mkdtemp(),
                                      base_url="/")

     self._field.storage = test_storage

def tearDown(self):
     self._field = self._default_storage
Run Code Online (Sandbox Code Playgroud)