Skip to content

Commit 6294230

Browse files
committed
Initial commit
0 parents  commit 6294230

File tree

9 files changed

+434
-0
lines changed

9 files changed

+434
-0
lines changed

.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export FLASK_APP=app
2+
export FLASK_ENV=development
3+
PYTHONPATH=${PYTHONPATH}:src

Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
###################################################################################
2+
# This Makefile is used for installing dependencies, running the dev server and #
3+
# running tests. #
4+
###################################################################################
5+
6+
# Run 'make help' if there is no specified target. -> i.e. 'make'
7+
.DEFAULT_GOAL := help
8+
9+
# Print a small manual on how this Makefile can be used
10+
help:
11+
@echo "usage:"
12+
@echo " make <target>"
13+
@echo "targets:"
14+
@echo " install Install project dependencies and git pre-commit hooks"
15+
@echo " run Run development server at http://localhost:5000"
16+
@echo " test Run all available tests of the project"
17+
@echo " help List usage and available targets"
18+
19+
# Installs project dependencies and git pre-commit hooks.
20+
install:
21+
pipenv install
22+
23+
# Runs the development server which will be served at http://localhost:5001
24+
run:
25+
pipenv run flask run
26+
27+
# Runs all tests of the project
28+
test:
29+
pipenv run pytest --cov=src --cov-report=html --cov-report=term --cov-branch test/

Pipfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[[source]]
2+
url = "https://pypi.org/simple"
3+
verify_ssl = true
4+
name = "pypi"
5+
6+
[packages]
7+
flask = "*"
8+
flask-sqlalchemy = "*"
9+
pytest = "*"
10+
pytest-mock = "*"
11+
12+
[dev-packages]
13+
14+
[requires]
15+
python_version = "3.9"

Pipfile.lock

Lines changed: 305 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Config(object):
2+
DEBUG = False
3+
TESTING = False
4+
SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:"
5+
6+
class ProductionConfig(Config):
7+
SQLALCHEMY_DATABASE_URI = 'mysql://user@localhost/foo'
8+
9+
class DevelopmentConfig(Config):
10+
DEBUG = True
11+
12+
class TestingConfig(Config):
13+
TESTING = True
14+
SQLALCHEMY_TRACK_MODIFICATIONS = False

src/__init__.py

Whitespace-only changes.

src/app.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import os
2+
from flask import Flask, jsonify
3+
from flask_sqlalchemy import SQLAlchemy
4+
from sqlalchemy.dialects.postgresql import VARCHAR
5+
6+
basedir = os.path.abspath(os.path.dirname(__file__))
7+
8+
9+
app = Flask(__name__) # instantiate app
10+
app.config.from_object("config.TestingConfig") # load testing config from config.py
11+
db = SQLAlchemy() # instantiate sqlalchemy
12+
db.init_app(app) # link sqlalchemy to app
13+
14+
# Example for a database model
15+
class MyModel(db.Model):
16+
id = db.Column("id", VARCHAR, primary_key=True, unique=True, nullable=False)
17+
18+
# Example route
19+
@app.route("/", methods=['GET'])
20+
def get_value():
21+
mod = MyModel.query.first()
22+
return jsonify(mod.id), 200

tests/conftest.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import pytest
2+
from flask import Flask
3+
from flask_sqlalchemy import SQLAlchemy
4+
from src.app import MyModel
5+
6+
7+
@pytest.fixture
8+
def mock_my_model():
9+
"""
10+
This fixture mocks the database model 'MyModel' which will have the id 'my_mock_id'.
11+
This id can be used in the test cases.
12+
"""
13+
my_model = MyModel(
14+
id="my_mock_id",
15+
)
16+
return my_model
17+
18+
19+
@pytest.fixture
20+
def mock_get_sqlalchemy(mocker):
21+
""" This fixture will mock the SQLAlchemy query response from the database """
22+
mock = mocker.patch(
23+
"flask_sqlalchemy._QueryProperty.__get__").return_value = mocker.Mock()
24+
return mock
25+
26+
27+
@pytest.fixture
28+
def flask_app_mock():
29+
""" Flask application mock set up. """
30+
app_mock = Flask(__name__)
31+
db = SQLAlchemy(app_mock)
32+
db.init_app(app_mock)
33+
return app_mock

tests/test_app.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from src.app import get_value
2+
3+
4+
def test_get_value(flask_app_mock, mock_my_model, mock_get_sqlalchemy):
5+
""" This test will call the function under test (get_value()) and succeeds if
6+
get_value() returns the ID of MyModel which shall be 'my_mock_id'."""
7+
mock_get_sqlalchemy.first.return_value = mock_my_model
8+
9+
with flask_app_mock.app_context():
10+
response = get_value() # call the function under test
11+
12+
# check if we've gotten our mocked model object
13+
assert response[0].json == "my_mock_id"

0 commit comments

Comments
 (0)