1

django version: 1.11, python version: 3.6.3

I found this stackoverflow question:

Unit Testing a Django Form with a FileField

and I like how there isn't an actual image/external file used for the unittest; however I tried these approaches:

from django.test import TestCase
from io import BytesIO
from PIL import Image
from my_app.forms import MyForm
from django.core.files.uploadedfile import InMemoryUploadedFile

class MyModelTest(TestCase):                    
    def test_valid_form_data(self):                    
        im_io = BytesIO() # BytesIO has to be used, StrinIO isn't working         
        im = Image.new(mode='RGB', size=(200, 200))         
        im.save(im_io, 'JPEG')                                  
        form_data = {
                'some_field': 'some_data'
            }                                               
        image_data = {   
                InMemoryUploadedFile(im_io, None, 'random.jpg', 'image/jpeg', len(im_io.getvalue()), None) 
            }    
        form = MyForm(data=form_data, files=image_data)             
        self.assertTrue(form.is_valid()) 

however, this always results in the following error message:

Traceback (most recent call last):
  File "/home/my_user/projects/my_app/products/tests/test_forms.py", line 44, in test_valid_form_data
    self.assertTrue(form.is_valid())
  File "/home/my_user/.virtualenvs/forum/lib/python3.6/site-packages/django/forms/forms.py", line 183, in is_valid
    return self.is_bound and not self.errors
  File "/home/my_user/.virtualenvs/forum/lib/python3.6/site-packages/django/forms/forms.py", line 175, in errors
    self.full_clean()
  File "/home/my_user/.virtualenvs/forum/lib/python3.6/site-packages/django/forms/forms.py", line 384, in full_clean
    self._clean_fields()
  File "/home/my_user/.virtualenvs/forum/lib/python3.6/site-packages/django/forms/forms.py", line 396, in _clean_fields
    value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
  File "/home/my_user/.virtualenvs/forum/lib/python3.6/site-packages/django/forms/widgets.py", line 423, in value_from_datadict
    upload = super(ClearableFileInput, self).value_from_datadict(data, files, name)
  File "/home/my_user/.virtualenvs/forum/lib/python3.6/site-packages/django/forms/widgets.py", line 367, in value_from_datadict
    return files.get(name)
AttributeError: 'set' object has no attribute 'get'

Why? I understand that .get() is a dictionary method, but I fail to see where it created a set.

Engineero
  • 12,340
  • 5
  • 53
  • 75
stetim94
  • 64
  • 1
  • 11

2 Answers2

3

image_data should be dict, without providing key {value} will create set object. You need to define it like this {key: value}. Fix to this:

image_data = {   
            'image_field': InMemoryUploadedFile(im_io, None, 'random.jpg', 'image/jpeg', len(im_io.getvalue()), None) 
        }   
neverwalkaloner
  • 46,181
  • 7
  • 92
  • 100
  • 1
    Oh wow, now i feel like an idiot, such a stupid mistake. Thank you so much for your time and help, its really appreciated :) – stetim94 Jan 03 '18 at 11:17
1

Without External File Code

from django.core.files.uploadedfile import SimpleUploadedFile
testfile = (
b'\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x00\x00\x00\x21\xf9\x04'
b'\x01\x0a\x00\x01\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02'
b'\x02\x4c\x01\x00\x3b')

avatar = SimpleUploadedFile('small.gif', testfile, content_type='image/gif')
Saad Mirza
  • 1,154
  • 14
  • 22