How to create cgi.FieldStorage for testing purposes?
Asked Answered
H

3

6

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?

Hinrichs answered 20/8, 2012 at 5:52 Comment(0)
H
5

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.

Hinrichs answered 21/8, 2012 at 6:0 Comment(1)
what should be the type of content?Waler
A
6

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)
Applicable answered 16/5, 2016 at 17:41 Comment(1)
what should be the type of content?Waler
H
5

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.

Hinrichs answered 21/8, 2012 at 6:0 Comment(1)
what should be the type of content?Waler
R
0

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'
Rarebit answered 9/2, 2022 at 11:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.