Problems trying to mock a Model within Flask-SQLAlchemy

后端 未结 2 828
不知归路
不知归路 2021-02-04 16:54

I\'m testing a Flask application that have some SQLAlchemy models using Flask-SQLAlchemy and I\'m having some problems trying to mock a few models to some methods that receive s

2条回答
  •  無奈伤痛
    2021-02-04 17:00

    So, I found a solution after banging my head on the keyboard for a few hours. The problem seems to be the following (if anyone knows better, please correct me).

    When I run mock.create_autospec(User), the mock module tries to inspect all attributes of User to create the adequate spec for the Mock object it will spit out. When this happens, it tries to inspect the attribute User.query, which can only be evaluated when you are inside the scope of a Flask app.

    This happens because when User.query is evaluated, an object is created that needs a valid session. This session is created by the create_scope_session method on the SQLAlchemy class inside Flask-SQLAlchemy.

    This method instantiates a class called SignallingSession whose __init__ method calls the SQLAlchemy.get_app method. This is the method that raises the RuntimeError when there's no app registered in the db.

    By patching the SignallingSession method everything works nicely. Since I don't want to interact with the database this is ok:

    import unittest
    import datetime
    
    import mock
    
    from actions import age
    
    
    @mock.patch("flask_sqlalchemy.SignallingSession", autospec=True)
    class TestModels(unittest.TestCase):
    
        def test_age(self, session):
            import database
    
            user = mock.create_autospec(database.User)
            user.birthday = datetime.date(year=1987, month=12, day=1)
            print age(user)
    

提交回复
热议问题