It isn’t always obvious how and where to patch Django internals when (unit) testing your application. If you have a model with a FileField and save an instance in a test, each time you run that test a file will be written to your file system if you use the default FileSystemStorage backend.

Consider the following example (Python 3.7 and Django 2.1 are used here):

# models.py
class Person(models.Model):
    name = models.CharField(max_length=100)
    cv = models.FileField()

# views.py
class PersonCreateView(CreateView):
    model = Person
    template_name = 'person_create.html'
    fields = '__all__'
    success_url = '/'

To prevent a file from being saved on disk, or even uploaded to somewhere else if you use an alternative storage backend, you can use dj-inmemorystorage and configure that as your storage backend during testing. A downside is that this will not work if you have a specific FileField or ImageField that uses a different storage backend, for example S3.

Luckily, there is a better way by using the builtin unittest.mock library (or the backported mock library on Python 2.7) to patch the save method of the storage class that is being used:

# tests.py
from io import StringIO
from unittest.mock import patch

from django.core.files.storage import Storage
from django.test import RequestFactory, TestCase

from people.models import Person
from people.views import PersonCreateView


class TestPersonCreateView(TestCase):
    @patch('django.core.files.storage.FileSystemStorage.save')
    def test_post(self, mock_save):
        mock_save.return_value = 'cv.doc'
        factory = RequestFactory()
        request = factory.post('/some-url/', {
            'name': 'John Doe',
            'cv': StringIO('test'),
        })
        response = PersonCreateView.as_view()(request)
        self.assertEqual(Person.objects.count(), 1)
        mock_save.assert_called_once()  # No file saved!

I have also stumbled on this blog post that mentions patching the default storage backend, but that also won’t work if you have set the storage argument for your FileField or ImageField. For instance, if you’re uploading files to S3 with the S3Boto3Storage backend you can patch it directly:

@patch('storages.backends.s3boto3.S3Boto3Storage.save')
def test_post(self, mock_save):
    ...