How can I unit test this Flask app?

孤街浪徒 提交于 2020-12-29 06:55:28

问题


I have a Flask app that is using Flask-Restless to serve an API.

I have just written some authentication that checks

  1. If the consumers host is recognised
  2. The request includes a hash (calculated by encrypting the request content for POST and URL for GET along with a secret API key) and
  3. The hash is valid

I want to be able to write some unit tests for this, but I'm not sure how because my functions use the request object. Should I be mocking the request object?

Would love some advice on this.

Config

API_CONSUMERS = [{'name': 'localhost',
                  'host': '12.0.0.1:5000',
                  'api_key': 'Ahth2ea5Ohngoop5'},
                 {'name': 'localhost2',
                  'host': '127.0.0.1:5001',
                  'api_key': 'Ahth2ea5Ohngoop6'}]

Authentication methods

import hashlib
from flask import request


def is_authenticated(app):
    """
    Checks that the consumers host is valid, the request has a hash and the
    hash is the same when we excrypt the data with that hosts api key

    Arguments:
    app -- instance of the application
    """
    consumers = app.config.get('API_CONSUMERS')
    host = request.host

    try:
        api_key = next(d['api_key'] for d in consumers if d['host'] == host)
    except StopIteration:
        app.logger.info('Authentication failed: Unknown Host (' + host + ')')
        return False

    if not request.headers.get('hash'):
        app.logger.info('Authentication failed: Missing Hash (' + host + ')')
        return False

    if request.method == 'GET':
        hash = calculate_hash_from_url(api_key)
    elif request.method == 'POST':
        hash = calculate_hash_from_content(api_key)

    if hash != request.headers.get('hash'):
        app.logger.info('Authentication failed: Hash Mismatch (' + host + ')')
        return False
    return True


def calculate_hash_from_url(api_key):
    """
    Calculates the hash using the url and that hosts api key

    Arguments:
    api_key -- api key for this host
    """
    data_to_hash = request.base_url + '?' + request.query_string
    data_to_hash += api_key
    return hashlib.sha1(request_uri).hexdigest()


def calculate_hash_from_content(api_key):
    """
    Calculates the hash using the request data and that hosts api key

    Arguments:
    api_key -- api key for this host
    """
    data_to_hash = request.data
    data_to_hash += api_key
    return hashlib.sha1(data_to_hash).hexdigest()

回答1:


test_request_object() did the trick, thanks monkey.

from flask import request

with app.test_request_context('/hello', method='POST'):
    # now you can do something with the request until the
    # end of the with block, such as basic assertions:
    assert request.path == '/hello'
    assert request.method == 'POST'



回答2:


I made a nose test suite that tested my Graffiti app by just calling the method and passing the URL segment as the method parameter. i.e.:

response = self.app.do_something("/item/1234567890")
assert response.status_code == 200


来源:https://stackoverflow.com/questions/13959209/how-can-i-unit-test-this-flask-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!