Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在sqlalchemy中模拟创建的时间?_Python_Unit Testing_Testing_Sqlalchemy_Mocking - Fatal编程技术网

Python 如何在sqlalchemy中模拟创建的时间?

Python 如何在sqlalchemy中模拟创建的时间?,python,unit-testing,testing,sqlalchemy,mocking,Python,Unit Testing,Testing,Sqlalchemy,Mocking,我在烧瓶应用程序中使用SQLAlchemy。在我的测试中,我尝试为我的条目模拟自动创建和更新时间。但我不明白它对炼金术是如何起作用的。例如,我尝试模拟datetime创建,但失败了。例如: class Entry(db.Model): __tablename__ = 'entries' created = db.Column(db.DateTime(), default=db.func.now()) updated = db.Column(db.DateTime(), d

我在烧瓶应用程序中使用SQLAlchemy。在我的测试中,我尝试为我的条目模拟自动创建和更新时间。但我不明白它对炼金术是如何起作用的。例如,我尝试模拟datetime创建,但失败了。例如:

class Entry(db.Model):
    __tablename__ = 'entries'
    created = db.Column(db.DateTime(), default=db.func.now())
    updated = db.Column(db.DateTime(), default=db.func.now(), onupdate=db.func.now())

class ViewTestCase(AppliactionTestCase):
    def test(self):
        with freeze_time("2014-06-01 16:00:00"):
            db.session.add(Entry())
            db.session.commit()
        entry = db.session.query(Entry).first()
        self.assertEqual(entry.created, datetime(2014, 6, 1, 16, 0, 0))

还有一个问题。如果我需要为条目刷新
更新的
,如何在没有更改的情况下强制保存条目?

仅冻结修补程序
datetime.datetime.now
。您可以通过以下两种方式之一解决此问题:

  • 使用
    mock.patch
    来修补
    db.func.now()
  • 现在使用
    default=datetime.datetime.now
    ,这样冷冻枪就能正确地修补它

  • sqlalchemy提供钩子
    sqlalchemy.event
    api来修补查询会话

    先决条件:炼金术、pytest、冻结、上下文库

    以@prokoptesev使用的flask sqlalchemy为例:

    class Entry(db.Model):
        __tablename__ = 'entries'
        created = db.Column(db.DateTime(), default=db.func.now())
        updated = db.Column(db.DateTime(), default=db.func.now(), onupdate=db.func.now())
    
    只需编写pytest fixtures来修补行创建时间:

    import datetime
    from flask_sqlalchemy import event
    from contextlib import contextmanager
    from freezegun import freeze_time
    
    import Entry
    # if you want the code be commonly used, change Entry to db.Model instead
    
    
    @contextmanager
    def patch_time(time_to_freeze, tick=True):
        with freeze_time(time_to_freeze, tick=tick) as frozen_time:
            def set_timestamp(mapper, connection, target):
               now = datetime.datetime.now()
               if hasattr(target, 'created'):
                   target.created = now
               if hasattr(target, 'updated'):
                   target.updated = now
            event.listen(Entry, 'before_insert', set_timestamp,
                         propagate=True)
            yield frozen_time
            event.remove(Entry, 'before_insert', set_timestamp)
    
    
    @pytest.fixture(scope='function')
    def patch_current_time():
        return patch_time
    
    然后编写pytest类型测试用例:

    def test_patch_insert_time(patch_current_time, assertions):
        with patch_current_time("2014-06-01 16:00:00", tick=False):
            db.session.add(Entry())
            db.session.commit()
        entry = db.session.query(Entry).first()
        assert entry.created == datetime(2014, 6, 1, 16, 0, 0)
    
    如果有人使用
    unittools
    或其他测试包,您也可以直接使用patch\u time函数:

    class ViewTestCase(AppliactionTestCase):
        def test(self):
            with patch_time("2014-06-01 16:00:00", tick=False):
                db.session.add(Entry())
                db.session.commit()
            entry = db.session.query(Entry).first()
            self.assertEqual(entry.created, datetime(2014, 6, 1, 16, 0, 0))
    

    快乐的编码。

    这对我不起作用。我不知道它在引擎盖下是如何工作的,但如果我在模型中使用
    default=datetime.datetime.now
    ,datetime已修补,但在已保存的模型中
    created
    返回当前时间。我如何修补
    db.func.now
    ?如果我错了,请纠正我
    db.func.now
    是保存模型时的数据库功能。可能是修补错误?相对于您的测试,
    条目
    类在哪里?抱歉,我不明白您的意思。