How do I mock PyMongo for testing with a Flask app? How do I mock PyMongo for testing with a Flask app? flask flask

How do I mock PyMongo for testing with a Flask app?


we can wrap app and mongo in a functionThis works because mongo is used as a local variable.

app.py

from flask import Flaskfrom flask_pymongo import PyMongodef get_app_with_config(config):    app = Flask(__name__)    app.config.from_object(config)    mongo = PyMongo(app)    @app.route("/")    def index():        pass    .    .        return app, mongo

then we can create a test file and an application execution file with different databases:

test_app.py

from app import get_app_with_configfrom config import TestConfigapp, mongo = get_app_with_config(TestConfig)

run.py

from app import get_app_with_configfrom config import RunConfigapp, mongo = get_app_with_config(RunConfig)if __name__ == '__main__':    app.run(port=8000)

Sample of config.py file:

class RunConfig:    MONGO_HOST = '192.168.1.37'    MONGO_PORT = 27017    MONGO_DBNAME = 'my_database'    MONGO_URI = f"mongodb://{MONGO_HOST}:{MONGO_PORT}/{MONGO_DBNAME}"class TestConfig:    MONGO_HOST = '192.168.1.37'    MONGO_PORT = 27017    MONGO_DBNAME = 'my_database_test'    MONGO_URI = f"mongodb://{MONGO_HOST}:{MONGO_PORT}/{MONGO_DBNAME}"    TESTING = True


Needed a quick fix so I edited app.py so that it only hard-fails if PyMongo doesn't initialise when the file is executed (i.e. it ignores PyMongo's failed initialisation when running unit-tests.)

app = Flask(__name__)app.config["MONGO_DBNAME"] = os.environ.get('DB_NAME')app.config["MONGO_URI"] = os.environ.get('MONGO_URI')app.secret_key = os.environ.get('SECRET')try:    mongodb = PyMongo(app).dbexcept ValueError:    """We don't provide a URI when running unit tests, so PyMongo will fail to initialize.    This is okay because we replace it with a version for testing anyway. """    print('PyMongo not initialized!')    mongodb = None...if __name__ == '__main__':    if not mongodb:        print('Cannot run. PyMongo failed to initialize. Double check environment variables.')        exit(1)    app.run(host=os.environ.get('IP'),            port=int(os.environ.get('PORT')),            debug=False)

In my tests file, I just assign the mocked mongoDB client to the app in the tests that need it. Definitely not the ideal solution.

def test_redacted(client, mongodb):    app.mongodb = mongodb    ...