Tornado: how to write unit-test for file-upload handlers in tornado

Created on 23 Jan 2015  路  6Comments  路  Source: tornadoweb/tornado

I write my unittest like this due to some experices on django unit-teset. but it not works. I saw the header and the body seems not handled, and I can't find any example or tutorial about this.

from os import path
from tornado.testing import AsyncHTTPTestCase

class ImageTestCase(AsyncHTTPTestCase):

    def test_post_return_ok(self):
        fpath = path.join(path.dirname(__file__), 'test.jpg')
        f = open(fpath)

        url = "/img"
        data = {
            "image": f,
        }

        response = self.fetch(url, method="POST",  body=data)
        print response.request.header
        print response.request.body

this result is somethind like this:

ipdb> response.request.body
'image=%3Copen+file+%27%2Fhome%2Fdaipeng%2Fprojects%2Fnext_chat%2Fnchat%2Ftests%2Ftest.jpg%27%2C+mode+%27r%27+at+0x360e150%3E'

ipdb> response.request.headers
{'Content-Type': 'application/x-www-form-urlencoded', 'Connection': 'close', 'Content-Length': '191', 'Host': u'localhost:42321', 'Accept-Encoding': 'gzip'}

Most helpful comment

I write a requestHandler to let others can upload a img to the sever. And I need to write unittest for it.
I know the http request need to be format correct. but the tornado seems not have such utils.
I finish my unittest like below, but It's not really a beauty solution.

import requests
from tornado.testing import AsyncHTTPTestCase


class ImageTest(AsyncHTTPTestCase):
    def test_post_return_ok(self):
        fpath = path.join(path.dirname(__file__), 'test.jpg')
        f = open(fpath)

        files = {"image": f}
        data = {}

        a = requests.Request(url="http://localhost/img",
                             files=files, data=data)
        prepare = a.prepare()
        content_type = prepare.headers.get('Content-Type')
        body = prepare.body

        url = "/api/upload_img"
        headers = {
            "Content-Type": content_type,
        }

        response = self.fetch(url, method='POST', body=body, headers=headers)

        self.assertEquals(response.code, 200)

All 6 comments

What did you expect? response.request is what you sent to the server; you want response.body and response.headers (and response.code) to see what the server returned to you.

Ah, I see now that it's sending image=%3Copen+file.... That's because you're not reading the file, you're passing the file handle itself as an argument. Try using "image": f.read()

I write a requestHandler to let others can upload a img to the sever. And I need to write unittest for it.
I know the http request need to be format correct. but the tornado seems not have such utils.
I finish my unittest like below, but It's not really a beauty solution.

import requests
from tornado.testing import AsyncHTTPTestCase


class ImageTest(AsyncHTTPTestCase):
    def test_post_return_ok(self):
        fpath = path.join(path.dirname(__file__), 'test.jpg')
        f = open(fpath)

        files = {"image": f}
        data = {}

        a = requests.Request(url="http://localhost/img",
                             files=files, data=data)
        prepare = a.prepare()
        content_type = prepare.headers.get('Content-Type')
        body = prepare.body

        url = "/api/upload_img"
        headers = {
            "Content-Type": content_type,
        }

        response = self.fetch(url, method='POST', body=body, headers=headers)

        self.assertEquals(response.code, 200)

@hackrole , @bdarnell , If I have to read the content out from local file to memory, then how to upload a large file (especially a large binary file)?

@leafjungle , I can not got your problem.Does you mean the profermance issues while uploading large file?

@leafjungle Look at the body_producer argument to AsyncHTTPClient.fetch to upload large files without loading the whole thing into memory at once.

Also, it's best if you don't reply to old closed issues. Stack Overflow is probably a better place for these kinds of questions.

Was this page helpful?
0 / 5 - 0 ratings