对于flask的test_client,请求式的包装器

时间:2016-12-12 19:57:12

标签: python python-requests werkzeug

我尝试为我的软件包进行可用的测试,但使用Flask.test_client与我发现难以使用的requests API非常不同。

我试图让requests.adapters.HTTPAdapter包装回复,但看起来werkzeug没有使用httplib(或urllib来构建)它拥有Response个对象。

知道如何做到这一点?对现有代码的引用将是最好的(谷歌搜索werkzeug +请求不会给出任何有用的结果)

非常感谢!!

2 个答案:

答案 0 :(得分:0)

据我所知,您需要的是嘲笑(请参阅What is Mocking?Mock Object)。好吧,下面列出了几个选项:

答案 1 :(得分:0)

您可以使用下面代码部分中定义的requests方法。 要使用它,您还需要定义下面代码中显示的get_auth_headers方法。

功能

  • Flask测试客户端周围的包装。
  • 自动设置请求标头。

      通过Content-Type: Application/json 时,
    • json 通过Basic Authentication时构建的
    • auth
  • 将您的json数据作为字符串转储到Flask测试客户端。
  • (缺失)将响应包装到requests.Response对象

<强>代码:

class MyTestCase(unittest.TestCase):
    def setUp(self):
        self.app = create_app('testing')
        self.client = self.app.test_client()
        self.app_context = self.app.app_context()
        self.app_context.push()
        db.create_all()

    def tearDown(self):
        db.session.remove()
        db.drop_all()
        self.app_context.pop()

    def get_auth_headers(self, username, password):
        return {
            'Authorization':
                'Basic ' + base64.b64encode(
                    (username + ':' + password).encode('utf-8')).decode('utf-8'),
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        }

    def requests(self, method, url, json={}, auth=(), **kwargs):
        """Wrapper around Flask test client to automatically set headers if JSON
        data is passed + dump JSON data as string."""
        if not hasattr(self.client, method):
            print("Method %s not supported" % method)
            return
        fun = getattr(self.client, method)

        # Set headers
        headers = {}
        if auth:
            username, password = auth
            headers = self.get_auth_headers(username, password)

        # Prepare JSON if needed
        if json:
            import json as _json
            headers.update({'Content-Type': 'application/json'})
            response = fun(url,
                           data=_json.dumps(json),
                           headers=headers,
                           **kwargs)
        else:
            response = fun(url, **kwargs)
        self.assertTrue(response.headers['Content-Type'] == 'application/json')
        return response

用法(在测试用例中):

def test_requests(self):
    url = 'http://localhost:5001'
    response = self.requests('get', url)
    response = self.requests('post', url, json={'a': 1, 'b': 2}, auth=('username', 'password'))
    ...

requests的唯一区别在于,您不必输入requests.get(...),而是必须输入self.request('get', ...)

如果您确实需要requests行为,则需要在{{1}周围定义自己的getputpostdelete包装}}

注意:

执行此操作的最佳方法可能是Flask API documentation

中所述的requests的子类化