gpt4 book ai didi

python - 模拟 SQLAlchemy 的默认属性

转载 作者:行者123 更新时间:2023-11-28 20:49:06 24 4
gpt4 key购买 nike

在我的模型中使用 defaultonupdate 字段时,我在模拟 SQLAlchemy 对象时遇到了一些问题:

def get_uuid():
return str(uuid.uuid4())

def get_now():
return db.func.now()

class BaseModel(db.Model):
__abstract__ = True

id = db.Column(UUIDType(binary=False), primary_key=True, nullable=False, default=get_uuid)
created_at = db.Column(db.DateTime(timezone=True), default=get_now(), nullable=False, index=True)

get_now()get_uuid() 行为不会改变,即使我在测试中尝试模拟它们也是如此:

def test_create_source(client, mocker):

mock = mocker.MagicMock(return_value='123e4567-e89b-12d3-a456-426655440000')
mocker.patch('myproject.models.get_uuid', mock)
mock = mocker.MagicMock(return_value=datetime.datetime(2019, 1, 1))
mocker.patch('myproject.models.get_now', mock)

resp = client.post('/sources', json={'name': 'My source'})
assert resp.json == {
'name': 'My source',
'id': '123e4567-e89b-12d3-a456-426655440000',
'createdAt': 'Tue, 01 Jan 2019 00:00:00 GMT',
'updatedAt': 'Tue, 01 Jan 2019 00:00:00 GMT'
}

### Results :

> assert resp.json == {
'name': 'My source',
'id': '123e4567-e89b-12d3-a456-426655440000',
'createdAt': 'Tue, 01 Jan 2019 00:00:00 GMT',
'updatedAt': 'Tue, 01 Jan 2019 00:00:00 GMT'
}
E AssertionError: assert {'createdAt':...17:38:38 GMT'} == {'createdAt': ...00:00:00 GMT'}
E Omitting 1 identical items, use -vv to show
E Differing items:
E {'id': '8eb074c0-41e9-436c-8f71-b4c6842f4809'} != {'id': '123e4567-e89b-12d3-a456-426655440000'}
E {'createdAt': 'Fri, 18 Jan 2019 17:38:38 GMT'} != {'createdAt': 'Tue, 01 Jan 2019 00:00:00 GMT'}
E {'updatedAt': 'Fri, 18 Jan 2019 17:38:38 GMT'} != {'updatedAt': 'Tue, 01 Jan 2019 00:00:00 GMT'}
E Use -v to get the full diff

tests/test_sources.py:17: AssertionError

我认为这是因为我的模型及其属性在进行测试之前已经导入和评估,所以 mock 在这里没有用。它在这个 post 的“模拟类助手”部分进行了解释,但我仍然无法解决我的问题:(

重现问题的完整可运行代码可在此处获得:https://github.com/ncrocfer/flaskmock

你有什么想法吗?

最佳答案

I think it's because my models and its attributes are already imported and evaluated before doing my test, so the mock is useless here.

关闭:您已将对函数 get_uuid() 的引用作为默认值传递给 id 以及调用 get_now() 的结果(函数表达式对象)默认为 created_at。事后更改这些名称在模块中绑定(bind)的内容对列不再有影响,这些列已经包含对对象本身的引用。

get_uuid() 的情况下,您应该模拟它正在调用的函数:

mock = mocker.MagicMock(return_value='123e4567-e89b-12d3-a456-426655440000')
mocker.patch('uuid.uuid4', mock)

get_now() 的情况下,您应该考虑不要在模型构建期间调用它:

class BaseModel(db.Model):
...
created_at = db.Column(..., default=get_now, ...)

这样你就可以再次模拟它正在调用的实际函数:

mock = mocker.MagicMock(return_value=datetime.datetime(2019, 1, 1))
mocker.patch('sqlalchemy.func.now', mock)

另一方面,也许你不应该断言任何关于 id 和测试中的时间戳,因为看起来重要的事情是验证名称是否设置正确。

关于python - 模拟 SQLAlchemy 的默认属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54259056/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com