如何使用自定义存储属性模拟django中的媒体文件目录?

时间:2017-12-21 10:11:36

标签: python django unit-testing

django版本:1.11,python版本:3.6.3

根据这两篇博客/文章:

https://joeray.me/mocking-files-and-file-storage-for-testing-django-models.html https://www.caktusgroup.com/blog/2013/06/26/media-root-and-django-tests/

理想情况下,我们会使用临时目录上传模拟文件。现在,模拟文件很容易。但是模拟目录并使用临时目录不能使用自定义存储属性

settings.py我有一个受保护的root来上传非公开图片:

MEDIA_URL = '/media/'

MEDIA_ROOT=os.path.join(BASE_DIR, "cdn", "media")
PROTECTED_ROOT = os.path.join(BASE_DIR, "cdn", "protected")
我在products/models.py中的

from django.conf import settings
from django.db import models
from django.core.files.storage import FileSystemStorage

class Product(models.Model):
    media = models.ImageField(
            # custom storage property
            storage=FileSystemStorage(location=settings.PROTECTED_ROOT)
        )

products/tests/test_views.py中的测试:

from django.test import TestCase
from unittest import mock
from products.models import Product
from django.core.files import File

class ProductViewSetup(TestCase):                                                                                                                                        

    @classmethod                                                                                                                                                         
    def setUpTestData(cls):
        file_mock = mock.MagicMock(spec=File, name='FileMock')                                                                                                           
        file_mock.name = 'test.jpg'
        cls.product = Product.objects.create(
                media=file_mock
            )

我以为我可以将caktusgroup博客中描述的代码自定义为:

class TempMediaMixin(object):                                                                                                                                            
    "Mixin to create MEDIA_ROOT in temp and tear down when complete."                                                                                                    

    def setup_test_environment(self):                                                                                                                                    
        "Create temp directory and update MEDIA_ROOT and default storage."                                                                                               
        super(TempMediaMixin, self).setup_test_environment()                                                                                                             
        settings._original_media_root = settings.MEDIA_ROOT                                                                                                              
        settings._original_file_storage = settings.DEFAULT_FILE_STORAGE                                                                                                  
        settings._original_protected_root = settings.PROTECTED_ROOT                                                                                                      
        self._temp_media = tempfile.mkdtemp()                                                                                                                            
        self._temp_protected = tempfile.mkdtemp()                                                                                                                        
        settings.MEDIA_ROOT = self._temp_media                                                                                                                           
        settings.PROTECTED_ROOT = self._temp_protected                                                                                                                   
        settings.DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'                                                                                    

    def teardown_test_environment(self):                                                                                                                                 
        "Delete temp storage."                                                                                                                                           
        super(TempMediaMixin, self).teardown_test_environment()                                                                                                          
        shutil.rmtree(self._temp_media, ignore_errors=True)                                                                                                              
        shutil.rmtree(self._temp_protected, ignore_errors=True)                                                                                                          
        settings.MEDIA_ROOT = settings._original_media_root                                                                                                              
        del settings._original_media_root                                                                                                                                
        settings.PROTECTED_ROOT = settings._original_protected_root                                                                                                      
        del settings._original_protected_root                                                                                                                            
        settings.DEFAULT_FILE_STORAGE = settings._original_file_storage                                                                                                  
        del settings._original_file_storage                                                                                                                              


class CustomTestSuiteRunner(TempMediaMixin, DiscoverRunner):                                                                                                             
    "Local test suite runner."  

我将TEST_RUNNER添加到settings.py,并且CustomTestSuiteRunner正在运行。还使用了临时目录,但仍将文件添加到我的PROTECTED_ROOT,我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

It seems like the custom test runner works fine when I overwrite the storage location in setUpTestData():

Product.media.field.storage.location = settings.PROTECTED_ROOT

This way it will use the temporary directory when using the custom test runner.

If you don't overwrite the storage location, it will use the storage defined in models.py.