Search code examples
djangoseleniumdjango-testingdjango-tests

Unit Test: How To Mock MEDIA_ROOT But Still Access A File That Is Stored In My Normal MEDIA Folder


Im testing one of my webpages POST functions. if request.method == 'POST' it generates a pdf and attaches it to the user. Every time I ran tests I was generating pdf files which were building up in my MEDIA folder and I had to manually delete them. I decided to look for ways to prevent this from happening and what seems to me to be the best way is to override my MEDIA_ROOT with a tempfile.

I am getting the following error message

FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Acer\\AppData\\Local\\Temp\\profile_pics\\default.jpg'

I am sure this is because I must create and log-in a user prior to running the test (I dont want to do this in setup as I must generate different types of users for different tests). Every time a user is created their profile picture is set to profile_pics\\default.jpg'.

My understanding is that the mocked MEDIA_ROOT is empty and doesnt contain the default profile pic, so the error is thrown.

My question is how can I circumvent this (ideally mocking the default.jpg image)? I found other solutions besides mocking the MEDIA_ROOT folder, but they seem quite hacky and id prefer to do it properly and hopefully learn from this.

tests.py

from django.test import override_settings
import tempfile

@override_settings(MEDIA_ROOT=tempfile.gettempdir())
def test_redirects_after_POST(self):
    user = User.objects.create_superuser('username')
    self.client.force_login(user)

    response = self.client.post(
        reverse('final_question'), data={
        'answer': 'this has me totally stumped'}
    )

    self.assertRedirects(response, reverse('page_2'))

Thank you.


Solution

  • The problem:

    PDF files are building up in your MEDIA_ROOT folder because there is nothing automatically deleting them.

    Recommended solution:

    I actually ran into this problem a few months ago myself, and the solution I found was the django-cleanup tool. It's very easy to install and integrate into your app (simply add it to your INSTALLED_APPS in settings.py).

    Note: This is assuming that your PDF files are in a FileField of one of your models. If that's not the case, then this solution won't work for you.