How to create cgi.FieldStorage for testing purposes?

1.9k views Asked by At

I am creating a utility to handle file uploads in webob-based applications. I want to write some unit tests for it.

My question is - as webob uses cgi.FieldStorage for uploaded files I would like to create a FieldStorage instance in a simple way (without emulating a whole request). What it the minimum code I need to do it (nothing fancy, emulating upload of a text file with "Lorem ipsum" content would be fine). Or is it a better idea to mock it?

3

There are 3 answers

1
zefciu On BEST ANSWER

After some research I came up with something like this:

def _create_fs(mimetype, content):                                              
    fs = cgi.FieldStorage()                                                     
    fs.file = fs.make_file()                                                    
    fs.type = mimetype                                                          
    fs.file.write(content)                                                      
    fs.file.seek(0)                                                             
    return fs             

This is sufficient for my unit tests.

0
Ricky Levi On

I was doing something like this, since in my script i'm using

import cgi

form = cgi.FieldStorage()

>>> # which result:
>>> FieldStorage(None, None, [])

When your URL contains query string it will look like this:

# URL: https://..../index.cgi?test=only
FieldStorage(None, None, [MiniFieldStorage('test', 'only')])

So i was just pushing manually MiniFieldStorage into the form variable

import cgi

fs = cgi.MiniFieldStorage('test', 'only')
>>> fs
MiniFieldStorage('test', 'only')

form = cgi.FieldStorage()
form.list.append(fs)

>>> form
>>> FieldStorage(None, None, [MiniFieldStorage('test', 'only')])

# Now you can call it with same functions
>>> form.getfirst('test')
'only'
1
Harut On

Your answer fails in python3. Here is my modification. I'm sure it is not perfect, but at least it works on both python2.7 and python3.5.

from io import BytesIO

def _create_fs(self, mimetype, content, filename='uploaded.txt', name="file"):
    content = content.encode('utf-8')
    headers = {u'content-disposition': u'form-data; name="{}"; filename="{}"'.format(name, filename),
               u'content-length': len(content),
               u'content-type': mimetype}
    environ = {'REQUEST_METHOD': 'POST'}
    fp = BytesIO(content)
    return cgi.FieldStorage(fp=fp, headers=headers, environ=environ)