Search code examples
python-3.xflaskflask-sqlalchemyflask-testing

Trouble unittesting Flask with SQLAlchemy


I have been messing around with trying to test my Flask application for a good while now but I cannot seem to get it to work.

I followed the docs for a bit and researched a while myself and ended up piecing something together (code below), however my implementation always returns the following error:

WinError 10061 Client refused connection

Anyways, here is the code im using, first one is the test and the latter one is my application factory:

./tests/test_api.py

from flask_testing import TestCase
import requests
from application import create_app, db


class TestApi(TestCase):
    def create_app(self):
        return create_app("test")

    def setUp(self):
        db.create_all()

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

    def test_available(self):
        response = requests.get("http://localhost:5000/api")
        self.assertEquals(response.status_code, 200)

./application/__init__.py

db = SQLAlchemy()


def create_app(env_type: str = "dev"):
    app = Flask(__name__, instance_relative_config=False)

    app.config["DEBUG"] = False
    app.config["TESTING"] = True
    app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:"
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

    db.init_app(app)

    with app.app_context():
        from . import views # imports my views
        from . import models
        app.add_url_rule("/api/tags", view_func=views.TagEndpoint.as_view("tag_endpoint"))
        app.add_url_rule("/api/tags/<item_name>", view_func=views.TagItemEndpoint.as_view("tag_item_endpoint"))

        return app

Any idea what I could be doing wrong?
Or maybe someone has some kind of minimal example for me that I could use to build off of (The docs didnt help me a whole lot).

EDIT: Before anyone asks, i did try to set the request url to both 127.0.0.1:5000/api and to my current devices ipv4 address.


Solution

  • I have tests like below, and they are working for me.

    from flask_testing import TestCase
    
    class BaseTestCase(TestCase):
        def create_app(self):
            return create_app('test')
    
    
    def create_app():
        #your create app code here
    
    
    class sampleTestCase(BaseTestCase):
        def setUp(self):
            db.create_all()
    
        def tearDown(self):
            db.session.remove()
            db.drop_all()
    
        def test_available(self):
            response = self.client.get("http://localhost:5000/api")
            self.assertEquals(response.status_code, 200)
    

    even your existing code should work, you just have to use self.client.get instead of requests.get