我的代码是这样的:
self.testbed.init_blobstore_stub()
upload_url = blobstore.create_upload_url('/image')
upload_url = re.sub('^http://testbed\.example\.com', '', upload_url)
response = self.testapp.post(upload_url, params={
'shopid': id,
'description': 'JLo',
}, upload_files=[('file', imgPath)])
self.assertEqual(response.status_int, 200)
怎么会显示404错误?由于某些原因,上传路径似乎根本不存在。
答案 0 :(得分:3)
你不能这样做。我认为问题是webtest(我假设是self.testapp来自哪里)对testbed blobstore功能不起作用。您可以在此question找到一些信息。
我的解决方案是覆盖unittest.TestCase
并添加以下方法:
def create_blob(self, contents, mime_type):
"Since uploading blobs doesn't work in testing, create them this way."
fn = files.blobstore.create(mime_type = mime_type,
_blobinfo_uploaded_filename = "foo.blt")
with files.open(fn, 'a') as f:
f.write(contents)
files.finalize(fn)
return files.blobstore.get_blob_key(fn)
def get_blob(self, key):
return self.blobstore_stub.storage.OpenBlob(key).read()
您还需要解决方案here。
对于我通常会在blobstore处理程序中获取或发布的测试,我会调用上面两种方法之一。它有点hacky但它确实有效。
我正在考虑的另一个解决方案是使用Selenium的HtmlUnit驱动程序。这将需要开发服务器运行,但应该允许完整测试blobstore和javascript(作为附带好处)。
答案 1 :(得分:2)
我认为Kekito是对的,你不能直接POST到upload_url。
但是如果你想测试BlobstoreUploadHandler,你可以通过以下方式伪造它通常从blobstore收到的POST请求。假设您的处理程序位于/ handler:
import email
...
def test_upload(self):
blob_key = 'abcd'
# The blobstore upload handler receives a multipart form request
# containing uploaded files. But instead of containing the actual
# content, the files contain an 'email' message that has some meta
# information about the file. They also contain a blob-key that is
# the key to get the blob from the blobstore
# see blobstore._get_upload_content
m = email.message.Message()
m.add_header('Content-Type', 'image/png')
m.add_header('Content-Length', '100')
m.add_header('X-AppEngine-Upload-Creation', '2014-03-02 23:04:05.123456')
# This needs to be valie base64 encoded
m.add_header('content-md5', 'd74682ee47c3fffd5dcd749f840fcdd4')
payload = m.as_string()
# The blob-key in the Content-type is important
params = [('file', webtest.forms.Upload('test.png', payload,
'image/png; blob-key='+blob_key))]
self.testapp.post('/handler', params, content_type='blob-key')
我通过挖掘blobstore代码来解决这个问题。重要的一点是blobstore发送给UploadHandler的POST请求不包含文件内容。相反,它包含一个“电子邮件”(嗯,编码如电子邮件中的信息),其中包含有关文件的元数据(内容类型,内容长度,上传时间和md5)。它还包含一个blob-key,可用于从blobstore中检索文件。