Unittest your Flask Application - Test your File Upload Method

In this post I'll shortly explain how to unittest your Flask-Upload-Method. Normally you don't want to use your hard drive, so an in memory file would be ideal.

def test_fileupload(self):
    user = User(email='john.doe@example.com', password='john1234', username='johnny')
    user.admin = False

    db.session().add(user)
    db.session().commit()

    with self.client as c:
        rv = login(c, 'johnny', 'john1234')
        self.assertTrue('index_page_7890' in str(rv.data))
        rv = c.get('/upload', follow_redirects=True)
        self.assertTrue("upload_site_234889" in str(rv.data))
        testfile_bytes = b"fdjasdfjksjkadf"
        testfile = (io.BytesIO(testfile_bytes), 'testing_134.txt')
        data = {'files[]': testfile}

        rv = c.post('/_upload', data=data, follow_redirects=True,
               content_type='multipart/form-data')
        print(rv)

        ret = rv.json['files'][0]
        self.assertEqual('testing_134.txt', ret['name'])
        url = ret['url']

        getfile = c.get(url, follow_redirects=True)

        self.assertEqual(testfile_bytes, getfile.data)

As you can see I use with self.client as c: to preserve the client context and navigate at my site. I created an user named johnny and committed him to the databse. Then I navigate to the upload site and verify it's the correct page. I do this with an tag which only renders when testing is enabled.

With testfile = (io.BytesIO(testfile_bytes), 'testing_134.txt') I create an tuple which contains the bytes from testfile_bytes. This is in my case some gibberish.

I then post the data to my upload method. As I use the JQuery File Upload from Blueimp my upload method returns a json. ret = rv.json['files'][0]

Then I do some checks , e.g. if the filename is correct and I get the Url from the returned Json.

Then I download the file from the returned url and verify it contains the same bytes I uploaded.