我的表格如下:
#forms.py
from django import forms
class MyForm(forms.Form):
title = forms.CharField()
file = forms.FileField()
#tests.py
from django.test import TestCase
from forms import MyForm
class FormTestCase(TestCase)
def test_form(self):
upload_file = open('path/to/file', 'r')
post_dict = {'title': 'Test Title'}
file_dict = {} #??????
form = MyForm(post_dict, file_dict)
self.assertTrue(form.is_valid())
如何构建 file_dict 以将 upload_file 传递给表单?
答案 0 :(得分:77)
到目前为止,我发现这种方式有效
from django.core.files.uploadedfile import SimpleUploadedFile
...
def test_form(self):
upload_file = open('path/to/file', 'rb')
post_dict = {'title': 'Test Title'}
file_dict = {'file': SimpleUploadedFile(upload_file.name, upload_file.read())}
form = MyForm(post_dict, file_dict)
self.assertTrue(form.is_valid())
答案 1 :(得分:21)
可能这不太正确,但我正在使用StringIO在单元测试中创建图像文件:
imgfile = StringIO('GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00'
'\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;')
imgfile.name = 'test_img_file.gif'
response = self.client.post(url, {'file': imgfile})
答案 2 :(得分:4)
这是另一种不要求您使用实际图像的方式。
编辑:已针对Python 3进行了更新。
from PIL import Image
from io import BytesIO # Python 2: from StringIO import StringIO
from django.core.files.uploadedfile import InMemoryUploadedFile
...
def test_form(self):
im = Image.new(mode='RGB', size=(200, 200)) # create a new image using PIL
im_io = BytesIO() # a BytesIO object for saving image
im.save(im_io, 'JPEG') # save the image to im_io
im_io.seek(0) # seek to the beginning
image = InMemoryUploadedFile(
im_io, None, 'random-name.jpg', 'image/jpeg', len(im_io.getvalue()), None
)
post_dict = {'title': 'Test Title'}
file_dict = {'picture': image}
form = MyForm(data=post_dict, files=file_dict)
答案 3 :(得分:0)
使用Python 3结合了本文和其他Stack文章中的一些想法。不需要外部文件或库。
from django.core.files.uploadedfile import SimpleUploadedFile
png_hex = ['\x89', 'P', 'N', 'G', '\r', '\n', '\x1a', '\n', '\x00',
'\x00', '\x00', '\r', 'I', 'H', 'D', 'R', '\x00',
'\x00', '\x00', '\x01', '\x00', '\x00', '\x00', '\x01',
'\x08', '\x02', '\x00', '\x00', '\x00', '\x90',
'w', 'S', '\xde', '\x00', '\x00', '\x00', '\x06', 'b', 'K',
'G', 'D', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\xf9', 'C', '\xbb', '\x7f', '\x00', '\x00',
'\x00', '\t', 'p', 'H', 'Y', 's', '\x00',
'\x00', '\x0e', '\xc3', '\x00', '\x00', '\x0e', '\xc3',
'\x01', '\xc7', 'o', '\xa8', 'd', '\x00', '\x00',
'\x00', '\x07', 't', 'I', 'M', 'E', '\x07', '\xe0', '\x05',
'\r', '\x08', '%', '/', '\xad', '+', 'Z',
'\x89', '\x00', '\x00', '\x00', '\x0c', 'I', 'D', 'A', 'T',
'\x08', '\xd7', 'c', '\xf8', '\xff', '\xff',
'?', '\x00', '\x05', '\xfe', '\x02', '\xfe', '\xdc', '\xcc',
'Y', '\xe7', '\x00', '\x00', '\x00', '\x00',
'I', 'E', 'N', 'D', '\xae', 'B', '`', '\x82']
valid_png_bin = str.encode("".join(png_hex))
png = SimpleUploadedFile("test.png", valid_png_bin)
post_dict = {'title': 'Test Title'}
file_dict = {'picture': png}
form = MyForm(data=post_dict, files=file_dict)
答案 4 :(得分:0)
可接受的答案有一个缺点,即您必须始终在您的环境中保留一个虚拟文件进行测试。
假设您是在团队中或在生产中工作,那不是很好的做法。 @xyres方法对我来说似乎更干净。可以进一步简化。
正如Python3 io docks所述,您可以执行以下操作:
loaded_file = BytesIO(b"some dummy bcode data: \x00\x01")
loaded_file.name = 'test_file_name.xls'
# and to load it in form
file_dict = {'file': SimpleUploadedFile(loaded_file.name, loaded_file.read())}
# Python3
from io import BytesIO
from django.core.files.uploadedfile import SimpleUploadedFile
class FormTestCase(TestCase)
def test_form(self):
# Simple and Clear
loaded_file = BytesIO(b"some dummy bcode data: \x00\x01")
loaded_file.name = 'test_file_name.xls'
post_dict = {'title': 'Test Title'}
file_dict = {'file': SimpleUploadedFile(loaded_file.name, loaded_file.read())}
form = MyForm(post_dict, file_dict)
self.assertTrue(form.is_valid())
还建议使用setUpTestData(cls)
和setUp(self)
类方法进行数据准备。
我个人发现Mozilla's intro to unit testing非常有用,也很简单。