如何为通过安全cookie验证用户的龙卷风处理程序编写单元测试?这是我想通过的虚拟测试的代码(和sudo代码)。我正在使用Tornado 3.1。
from tornado.web import Application, RequestHandler
from tornado.escape import to_unicode, json_decode, json_encode
from tornado.testing import AsyncHTTPTestCase
class MainHandler(RequestHandler):
"""
Base handler to authenticate user via a secure cookie.
This is used for an API.
"""
def get(self):
user = self.get_secure_cookie('user')
if user == 'user_email':
self.write('sucess')
else:
self.write('fail')
class UserAPITest(AsyncHTTPTestCase):
def get_app(self):
self.app = Application([('/', MainHandler)],
cookie_secret='asdfasdf')
return self.app
def test_user_profile_annoymous(self):
#SUDO CODE (what should go here?)
#cookie = make_secure_cookie('user', 'user_email', cookie_secret)
#headers = {'Cookie':cookie}
response = self.fetch('/', method='GET', headers=headers)
self.assertEqual('sucess', to_unicode(response.body) )
答案 0 :(得分:9)
使用mock:
import mock
...
class UserAPITest(AsyncHTTPTestCase):
def get_app(self):
self.app = Application([('/', MainHandler)],
cookie_secret='asdfasdf')
return self.app
def test_user_profile_annoymous(self):
with mock.patch.object(MainHandler, 'get_secure_cookie') as m:
m.return_value = 'user_email'
response = self.fetch('/', method='GET')
self.assertEqual('sucess', to_unicode(response.body) )
答案 1 :(得分:6)
您似乎可以尝试使用create_signed_value
模块中的tornado.web
函数:
from tornado.web import create_signed_value
class UserAPITest(AsyncHTTPTestCase):
def get_app(self):
self.app = Application([('/', MainHandler)],
cookie_secret='asdfasdf')
return self.app
def test_user_profile_annoymous(self):
cookie_name, cookie_value = 'Cookie', 'value'
secure_cookie = create_signed_value(
self.app.settings["cookie_secret"],
cookie_name,
cookie_value)
headers = {'Cookie': '='.join((cookie_name, secure_cookie))}
response = self.fetch('/', method='GET', headers=headers)
self.assertEqual('success', response.body)
答案 2 :(得分:0)
如果您想通过龙卷风REST API导入excel或要对处理程序进行单元测试,这可能对您有所帮助。它可以完美地构成我的应用程序。 在这里,我通过REST中的表单数据标头传递excel。
如果要使用Cookie编写其他Rest API的测试用例,则可能会有所帮助。
import json
import os.path
import requests
import sys
import time
import tornado.testing
import tornado.web
import unittest
import unittest.mock as mock
from http import cookies
from tornado.options import define, options, parse_command_line
from portal.handlers import ListHandler,excelimportHandler # handlers created in tornado
APP_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) # root location where your file is existing
sys.path.append(os.path.join(APP_ROOT, '..')) # joining file with root path
from portal.library.helpers import get_env_conf, read_env_conf # functionality to get and resd the the environment config file.
os.environ["ASYNC_TEST_TIMEOUT"] = str(60) # It will wait for the API for response
LIST = '/data/list'
IMPORT_EXCEL = '/import/excel'
class ProxyServerAPITest(tornado.testing.AsyncHTTPTestCase):
def __init__(self, *rest):
self.cookie = cookies.SimpleCookie()
define("env", default="localtest", help="Environment")
define("env_conf_path", default="", help="Environment config file path")
parse_command_line()
'''
reading the env config file for unit test cases
'''
if options.env_conf_path:
env_conf_path = options.env_conf_path
env_conf = read_env_conf(env_conf_path)
else:
env_conf = get_env_conf(options.env)
self.api_engine_address = env_conf.get("api_engine_address")
self.api_token = env_conf.get("api_token")
self.api_username = env_conf.get("api_username")
self.elasticsearch_index = env_conf.get("elasticsearch_index")
tornado.testing.AsyncHTTPTestCase.__init__(self, *rest)
def get_app(self):
env = mock.MagicMock(return_value='xyz') # mocking config file
def get(key):
"""
whenever in handlers, if these parameters will be called from there config files
it will take the parameters
of config file of unit test cases.
"""
if key == "api_username":
return self.api_username
elif key == "api_engine_address":
return self.api_engine_address
elif key == 'api_token':
return self.api_token
elif key == 'elasticsearch_index':
return self.elasticsearch_index
env.get = get
application = tornado.web.Application(
[
(LIST, ListHandler, dict(env_conf=env)),
(IMPORT_EXCEL, excelimportHandler, dict(env_conf=env)),
],
cookie_secret="cookie-secret")
return application
def _update_cookies(self, headers):
"""
It will take the cookies that will be passed in whole application.
"""
try:
sc = headers['Set-Cookie']
tempcookies = tornado.escape.native_str(sc)
tempcookies_dict = tempcookies.split('/,')
self.cookie.update(
cookies.SimpleCookie(tempcookies_dict[0].split(';')[0] + ';' + tempcookies_dict[1].split(';')[0] + ';' +
tempcookies_dict[2].split(';')[0]))
except KeyError:
return
def fetch(self, url, new_headers=None, *r, **kw):
"""
This function will set the headers and cookies for the Tornado application
"""
if 'follow_redirects' not in kw:
kw['follow_redirects'] = False
header = {}
hs = self.cookie.output()
header['Cookie'] = hs
if hs != '':
hs = hs.split('\r\n')
hs = hs[0].split('-Cookie:')[1] + ";" + hs[1].split('-Cookie:')[1] + ";" + hs[2].split('-Cookie:')[1]
header['Cookie'] = hs
if new_headers:
"""
These headers will be used if we wiil deal with excel file.
"""
header.update(new_headers)
resp = tornado.testing.AsyncHTTPTestCase.fetch(self, url, headers=header, *r, **kw)
self._update_cookies(resp.headers)
return resp
def find_body_headers_of_excel(self, file_name):
"""
This function will provide the encrypted form of the excel in body and proper headers
that to be passed in API to import the excel using REST.
"""
fpath = os.path.join(os.path.dirname(__file__), file_name)
f = open(fpath, 'rb')
files = {"file": f}
data = {}
a = requests.Request(method='POST', url="http://abc/img/test",
files=files, data=data)
prepare = a.prepare()
content_type = prepare.headers.get('Content-Type')
body = prepare.body
headers = {
"Content-Type": content_type,
}
return headers, body
def test_proxy_api(self):
headers, body = self.find_body_headers_of_excel('excel.xlsx')
resp = self.fetch(IMPORT_EXCEL, method='POST', body=body, connect_timeout=1000, request_timeout=1000,
new_headers=headers)
self.assertEqual(200, resp.code)
resp = self.fetch(LIST, method='GET', connect_timeout=1000, request_timeout=1000)
self.assertEqual(200, resp.code)
if __name__ == '__main__':
unittest.main()