Srujan
Srujan

Reputation: 13

Flask unittesting API requests

I am trying to write unit test cases for flas api server. Can someeone please suggest ow to get rid of auth.login_required.

Tried mocking auth, but of no use.

with test_client its not hitting code block too.

api.py

from flask import Flask
from flask.ext.httpauth import HTTPBasicAuth

app = Flask(__name__)
auth = HTTPBasicAuth()

@app.route('/')
@auth.login_required
def index():
    print "In index"
    response.status_code = 200
    return response

Tried following http://flask.pocoo.org/docs/0.12/testing/

from src.api import app
from unittest import TestCase

class TestIntegrations(TestCase):
    def setUp(self):
        self.app = app.test_client()
    def test_thing(self):
        response = self.app.get('/')

Can someone please help ??

Upvotes: 1

Views: 2368

Answers (1)

Borys Serebrov
Borys Serebrov

Reputation: 16172

There are two ways to do so - first is to disable authorization in tests:

// in your test module 
from api import app, auth
import unittest

@auth.verify_password
def verify_password(user, password):
    """Overwrite password check to always pass.

    This works even if we send no auth data."""
    return True

Another approach is to actually send the auth headers from tests (this way you can also test your authorization system):

from api import app
from base64 import b64encode
import unittest


class ApiClient:
    """Performs API requests."""

    def __init__(self, app):
        self.client = app.test_client()

    def get(self, url, **kwargs):
        """Sends GET request and returns the response."""
        return self.client.get(url, headers=self.request_headers(), **kwargs)

    def request_headers(self):
        """Returns API request headers."""
        auth = '{0}:{1}'.format('user', 'secret')
        return {
            'Accept': 'application/json',
            'Authorization': 'Basic {encoded_login}'.format(
                encoded_login=b64encode(auth.encode('utf-8')).decode('utf-8')
            )
        }


class TestIntegrations(unittest.TestCase):

    def setUp(self):
        self.app = ApiClient(app)

    def test_thing(self):
        response = self.app.get('/')
        print(response.data)

The ApiClient helper can also define post, delete methods which will be similar to get.

The full source code with examples is here.

Upvotes: 2

Related Questions