Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking current_app in Flask unit pytest

I want to unit test following function:

from flask import current_app

def fuu():
    current_app.logger.info('hello world')
    any = current_app.config['any']

Without any special context handling I receive following error message:

E           This typically means that you attempted to use functionality that needed
E           to interface with the current application object in some way. To solve
E           this, set up an application context with app.app_context().  See the
E           documentation for more information.

After reading about Flask context, I came up with a working solution:

@classmethod
def setUpClass(cls):
    app = app_factory.create_app()
    ctx = app.app_context()
    ctx.push()
    cls.app = app

But the point is that I do not want to deal with any flask contexts in UNIT tests. I want to have a plain unit test, in which all collaborators can be mocked, so that the system under test just deals with mocked instance, in this case for current_app as well. Having flask context is pretty fine for integration testing, but not for unit testing.

I am searching for something similar like this:

 @patch('flask.current_app')

Is there any way to achieve this?

EDIT #1

@Gabriel C

service.py

from flask import current_app

def fuu():
    current_app.logger.info('hello world')

service_test.py

import unittest
from unittest.mock import patch

class TestService(unittest.TestCase):

@patch('flask.current_app')
def test_generate_image_happy_path(self, mock):
    from service import fuu
    fuu()
    assert 1 == 1

This fails for the same exact reason:

E           RuntimeError: Working outside of application context.
like image 710
Christopher Will Avatar asked Sep 15 '19 20:09

Christopher Will


Video Answer


1 Answers

Answering for anyone that runs into the same issue. What you can do is create a dummy Flask app and use its context in your test. No need to patch anything.

import unittest
from service import fuu


class TestService(unittest.TestCase):
    app = Flask('test')

    def test_generate_image_happy_path(self):
        with app.app_context():
            fuu()
            assert 1 == 1

Of course if you want to have access to your Flask config, you'd have to pass that in to this dummy app.

like image 86
Darius Cosden Avatar answered Sep 21 '22 13:09

Darius Cosden